Merge "Make isSystemProvider field final" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 1ae9ada..3790a96 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -21,6 +21,7 @@
     java_aconfig_libraries: [
         // !!! KEEP THIS LIST ALPHABETICAL !!!
         "aconfig_mediacodec_flags_java_lib",
+        "aconfig_trade_in_mode_flags_java_lib",
         "android-sdk-flags-java",
         "android.adaptiveauth.flags-aconfig-java",
         "android.app.appfunctions.flags-aconfig-java",
@@ -1559,6 +1560,10 @@
     name: "android.crashrecovery.flags-aconfig-java",
     aconfig_declarations: "android.crashrecovery.flags-aconfig",
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.crashrecovery",
+    ],
 }
 
 java_aconfig_library {
diff --git a/Android.bp b/Android.bp
index 252aeef..b569df2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -109,7 +109,7 @@
         ":android.hardware.radio.voice-V3-java-source",
         ":android.hardware.security.keymint-V3-java-source",
         ":android.hardware.security.secureclock-V1-java-source",
-        ":android.hardware.thermal-V2-java-source",
+        ":android.hardware.thermal-V3-java-source",
         ":android.hardware.tv.tuner-V3-java-source",
         ":android.security.apc-java-source",
         ":android.security.authorization-java-source",
diff --git a/boot/boot-image-profile-extra.txt b/boot/boot-image-profile-extra.txt
index e3b187e..11ca1dc 100644
--- a/boot/boot-image-profile-extra.txt
+++ b/boot/boot-image-profile-extra.txt
@@ -19,3 +19,7 @@
 # methods are latency sensitive is difficult. For example, this method is executed
 # in the system server, not on the UI thread of an app.
 HSPLandroid/graphics/Color;->luminance()F
+
+# For now, compile all methods in MessageQueue to avoid performance cliffs for
+# flagged/evolving hot code paths. See: b/338098106
+HSPLandroid/os/MessageQueue;->*
diff --git a/core/api/current.txt b/core/api/current.txt
index a8b9e33..73b35b2 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -16369,6 +16369,7 @@
     field public static final int UNKNOWN = 0; // 0x0
     field public static final int Y8 = 538982489; // 0x20203859
     field public static final int YCBCR_P010 = 54; // 0x36
+    field @FlaggedApi("android.media.codec.p210_format_support") public static final int YCBCR_P210 = 60; // 0x3c
     field public static final int YUV_420_888 = 35; // 0x23
     field public static final int YUV_422_888 = 39; // 0x27
     field public static final int YUV_444_888 = 40; // 0x28
@@ -18718,6 +18719,7 @@
     field public static final long USAGE_VIDEO_ENCODE = 65536L; // 0x10000L
     field public static final int YCBCR_420_888 = 35; // 0x23
     field public static final int YCBCR_P010 = 54; // 0x36
+    field @FlaggedApi("android.media.codec.p210_format_support") public static final int YCBCR_P210 = 60; // 0x3c
   }
 
   @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public final class OverlayProperties implements android.os.Parcelable {
@@ -22985,6 +22987,7 @@
     field public static final int COLOR_FormatYUV444Flexible = 2135181448; // 0x7f444888
     field @Deprecated public static final int COLOR_FormatYUV444Interleaved = 29; // 0x1d
     field public static final int COLOR_FormatYUVP010 = 54; // 0x36
+    field @FlaggedApi("android.media.codec.p210_format_support") public static final int COLOR_FormatYUVP210 = 60; // 0x3c
     field @Deprecated public static final int COLOR_QCOM_FormatYUV420SemiPlanar = 2141391872; // 0x7fa30c00
     field @Deprecated public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
     field public static final String FEATURE_AdaptivePlayback = "adaptive-playback";
@@ -52491,6 +52494,7 @@
     method public android.graphics.Canvas lockHardwareCanvas();
     method public void readFromParcel(android.os.Parcel);
     method public void release();
+    method @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") public void setFrameRate(@NonNull android.view.Surface.FrameRateParams);
     method public void setFrameRate(@FloatRange(from=0.0) float, int, int);
     method public void setFrameRate(@FloatRange(from=0.0) float, int);
     method @Deprecated public void unlockCanvas(android.graphics.Canvas);
@@ -52507,6 +52511,22 @@
     field public static final int ROTATION_90 = 1; // 0x1
   }
 
+  @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") public static class Surface.FrameRateParams {
+    method @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") public int getChangeFrameRateStrategy();
+    method @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") public float getDesiredMaxRate();
+    method @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") public float getDesiredMinRate();
+    method @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") public float getFixedSourceRate();
+    field @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") public static final android.view.Surface.FrameRateParams IGNORE;
+  }
+
+  @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") public static final class Surface.FrameRateParams.Builder {
+    ctor public Surface.FrameRateParams.Builder();
+    method @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") @NonNull public android.view.Surface.FrameRateParams build();
+    method @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") @NonNull public android.view.Surface.FrameRateParams.Builder setChangeFrameRateStrategy(int);
+    method @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") @NonNull public android.view.Surface.FrameRateParams.Builder setDesiredRateRange(@FloatRange(from=0.0) float, @FloatRange(from=0.0) float);
+    method @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_api") @NonNull public android.view.Surface.FrameRateParams.Builder setFixedSourceRate(@FloatRange(from=0.0) float);
+  }
+
   public static class Surface.OutOfResourcesException extends java.lang.RuntimeException {
     ctor public Surface.OutOfResourcesException();
     ctor public Surface.OutOfResourcesException(String);
@@ -61755,7 +61775,7 @@
   public final class BackEvent {
     ctor public BackEvent(float, float, float, int);
     ctor @FlaggedApi("com.android.window.flags.predictive_back_timestamp_api") public BackEvent(float, float, float, int, long);
-    method @FlaggedApi("com.android.window.flags.predictive_back_timestamp_api") public long getFrameTime();
+    method @FlaggedApi("com.android.window.flags.predictive_back_timestamp_api") public long getFrameTimeMillis();
     method @FloatRange(from=0, to=1) public float getProgress();
     method public int getSwipeEdge();
     method public float getTouchX();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 207f4b5..f04df2f 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -9429,6 +9429,7 @@
     method public int getSignalStrength();
     method public int getSnr();
     method public int getSpectralInversion();
+    method @FlaggedApi("android.media.tv.flags.tuner_w_apis") @NonNull public android.media.tv.tuner.frontend.StandardExt getStandardExt();
     method @NonNull public int[] getStreamIds();
     method public int getSymbolRate();
     method @IntRange(from=0, to=65535) public int getSystemId();
@@ -9483,6 +9484,7 @@
     field public static final int FRONTEND_STATUS_TYPE_SIGNAL_STRENGTH = 6; // 0x6
     field public static final int FRONTEND_STATUS_TYPE_SNR = 1; // 0x1
     field public static final int FRONTEND_STATUS_TYPE_SPECTRAL = 10; // 0xa
+    field @FlaggedApi("android.media.tv.flags.tuner_w_apis") public static final int FRONTEND_STATUS_TYPE_STANDARD_EXT = 47; // 0x2f
     field public static final int FRONTEND_STATUS_TYPE_STREAM_IDS = 39; // 0x27
     field public static final int FRONTEND_STATUS_TYPE_SYMBOL_RATE = 7; // 0x7
     field public static final int FRONTEND_STATUS_TYPE_T2_SYSTEM_ID = 29; // 0x1d
@@ -9774,6 +9776,11 @@
     method public default void onUnlocked();
   }
 
+  @FlaggedApi("android.media.tv.flags.tuner_w_apis") public final class StandardExt {
+    method public int getDvbsStandardExt();
+    method public int getDvbtStandardExt();
+  }
+
 }
 
 package android.media.voice {
diff --git a/core/java/Android.bp b/core/java/Android.bp
index d12e1bf..9875efe 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -345,6 +345,13 @@
 }
 
 filegroup {
+    name: "service-crashrecovery-shared-srcs",
+    srcs: [
+        "android/util/IndentingPrintWriter.java",
+    ],
+}
+
+filegroup {
     name: "incremental_aidl",
     srcs: [
         "android/os/incremental/IIncrementalServiceConnector.aidl",
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index ffb920b..f880901 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -501,7 +501,7 @@
             in String shareDescription);
 
     void requestInteractiveBugReport();
-    void requestBugReportWithExtraAttachment(in Uri extraAttachment);
+    void requestBugReportWithExtraAttachments(in List<Uri> extraAttachment);
     void requestFullBugReport();
     void requestRemoteBugReport(long nonce);
     boolean launchBugReportHandlerApp();
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index acedef0..c93a6dd 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -30,20 +30,16 @@
 import android.os.Process;
 import android.os.SystemClock;
 import android.os.SystemProperties;
-import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.BackgroundThread;
-import com.android.internal.util.FastPrintWriter;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -1494,6 +1490,7 @@
     final static String NAME_LIKE = "-name-like=";
     final static String PROPERTY_CONTAINS = "-property-has=";
     final static String PROPERTY_LIKE = "-property-like=";
+    final static String BRIEF = "-brief";
 
     /**
      * Return true if any argument is a detailed specification switch.
@@ -1539,6 +1536,21 @@
         return false;
     }
 
+    /**
+     * helper method to check if dump should be skipped due to zero values
+     * @param args takes command arguments to check if -brief is present
+     * @return True if dump should be skipped
+     */
+    private boolean skipDump(String[] args) {
+        for (String a : args) {
+            if (a.equals(BRIEF)) {
+                return (mSkips[NONCE_CORKED] + mSkips[NONCE_UNSET] + mSkips[NONCE_DISABLED]
+                      + mSkips[NONCE_BYPASS] + mHits + mMisses) == 0;
+            }
+        }
+        return false;
+    }
+
     private void dumpContents(PrintWriter pw, boolean detailed, String[] args) {
         // If the user has requested specific caches and this is not one of them, return
         // immediately.
@@ -1549,25 +1561,28 @@
         NonceHandler.Stats stats = mNonce.getStats();
 
         synchronized (mLock) {
-            pw.println(formatSimple("  Cache Name: %s", cacheName()));
-            pw.println(formatSimple("    Property: %s", mPropertyName));
-            final long skips = mSkips[NONCE_CORKED] + mSkips[NONCE_UNSET] + mSkips[NONCE_DISABLED]
-                    + mSkips[NONCE_BYPASS];
-            pw.println(formatSimple(
-                    "    Hits: %d, Misses: %d, Skips: %d, Clears: %d",
-                    mHits, mMisses, skips, mClears));
-            pw.println(formatSimple(
-                    "    Skip-corked: %d, Skip-unset: %d, Skip-bypass: %d, Skip-other: %d",
-                    mSkips[NONCE_CORKED], mSkips[NONCE_UNSET],
-                    mSkips[NONCE_BYPASS], mSkips[NONCE_DISABLED]));
-            pw.println(formatSimple(
-                    "    Nonce: 0x%016x, Invalidates: %d, CorkedInvalidates: %d",
-                    mLastSeenNonce, stats.invalidated, stats.corkedInvalidates));
-            pw.println(formatSimple(
-                    "    Current Size: %d, Max Size: %d, HW Mark: %d, Overflows: %d",
-                    mCache.size(), mMaxEntries, mHighWaterMark, mMissOverflow));
-            pw.println(formatSimple("    Enabled: %s", mDisabled ? "false" : "true"));
-            pw.println("");
+            if (!skipDump(args)) {
+                pw.println(formatSimple("  Cache Name: %s", cacheName()));
+                pw.println(formatSimple("    Property: %s", mPropertyName));
+                final long skips =
+                        mSkips[NONCE_CORKED] + mSkips[NONCE_UNSET] + mSkips[NONCE_DISABLED]
+                                + mSkips[NONCE_BYPASS];
+                pw.println(formatSimple(
+                        "    Hits: %d, Misses: %d, Skips: %d, Clears: %d",
+                        mHits, mMisses, skips, mClears));
+                pw.println(formatSimple(
+                        "    Skip-corked: %d, Skip-unset: %d, Skip-bypass: %d, Skip-other: %d",
+                        mSkips[NONCE_CORKED], mSkips[NONCE_UNSET],
+                        mSkips[NONCE_BYPASS], mSkips[NONCE_DISABLED]));
+                pw.println(formatSimple(
+                        "    Nonce: 0x%016x, Invalidates: %d, CorkedInvalidates: %d",
+                        mLastSeenNonce, stats.invalidated, stats.corkedInvalidates));
+                pw.println(formatSimple(
+                        "    Current Size: %d, Max Size: %d, HW Mark: %d, Overflows: %d",
+                        mCache.size(), mMaxEntries, mHighWaterMark, mMissOverflow));
+                pw.println(formatSimple("    Enabled: %s", mDisabled ? "false" : "true"));
+                pw.println("");
+            }
 
             // No specific cache was requested.  This is the default, and no details
             // should be dumped.
diff --git a/core/java/android/appwidget/OWNERS b/core/java/android/appwidget/OWNERS
index 1910833..0e85d5b 100644
--- a/core/java/android/appwidget/OWNERS
+++ b/core/java/android/appwidget/OWNERS
@@ -3,3 +3,5 @@
 pinyaoting@google.com
 suprabh@google.com
 sunnygoyal@google.com
+zakcohen@google.com
+shamalip@google.com
diff --git a/core/java/android/appwidget/flags.aconfig b/core/java/android/appwidget/flags.aconfig
index ac9263c..3839b5f 100644
--- a/core/java/android/appwidget/flags.aconfig
+++ b/core/java/android/appwidget/flags.aconfig
@@ -74,3 +74,12 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+  name: "use_smaller_app_widget_radius"
+  namespace: "app_widgets"
+  description: "Updates system corner radius for app widgets to 24.dp instead of 28.dp"
+  bug: "373351337"
+  is_exported: true
+  is_fixed_read_only: true
+}
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index 5b38942..5f439b1 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -342,3 +342,11 @@
     bug: "292261144"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "change_launcher_badging"
+    namespace: "package_manager_service"
+    description: "Feature flag to introduce a new way to change the launcher badging."
+    bug: "364760703"
+    is_fixed_read_only: true
+}
diff --git a/core/java/android/hardware/HardwareBuffer.java b/core/java/android/hardware/HardwareBuffer.java
index 9395844..44115c8 100644
--- a/core/java/android/hardware/HardwareBuffer.java
+++ b/core/java/android/hardware/HardwareBuffer.java
@@ -66,6 +66,7 @@
             DS_FP32UI8,
             S_UI8,
             YCBCR_P010,
+            YCBCR_P210,
             R_8,
             R_16,
             RG_1616,
@@ -111,6 +112,16 @@
      * little-endian value, with the lower 6 bits set to zero.
      */
     public static final int YCBCR_P010    = 0x36;
+    /**
+     * <p>Android YUV P210 format.</p>
+     *
+     * P210 is a 4:2:2 YCbCr semiplanar format comprised of a WxH Y plane
+     * followed by a WxH CbCr plane. Each sample is represented by a 16-bit
+     * little-endian value, with the lower 6 bits set to zero.
+     */
+    @FlaggedApi(android.media.codec.Flags.FLAG_P210_FORMAT_SUPPORT)
+    public static final int YCBCR_P210    = 0x3c;
+
     /** Format: 8 bits red */
     @FlaggedApi(com.android.graphics.hwui.flags.Flags.FLAG_REQUESTED_FORMATS_V)
     public static final int R_8           = 0x38;
diff --git a/core/java/android/hardware/fingerprint/FingerprintCallback.java b/core/java/android/hardware/fingerprint/FingerprintCallback.java
index 24e9f9d..e4fbe6e 100644
--- a/core/java/android/hardware/fingerprint/FingerprintCallback.java
+++ b/core/java/android/hardware/fingerprint/FingerprintCallback.java
@@ -189,7 +189,7 @@
             mEnrollmentCallback.onAcquired(acquireInfo == FINGERPRINT_ACQUIRED_GOOD);
         }
         final String msg = getAcquiredString(context, acquireInfo, vendorCode);
-        if (msg == null || msg.isEmpty()) {
+        if (msg == null) {
             return;
         }
         // emulate HAL 2.1 behavior and send real acquiredInfo
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 7f1cac0..590c4d6 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -1517,7 +1517,7 @@
      */
     public static String getAcquiredString(Context context, int acquireInfo, int vendorCode) {
         switch (acquireInfo) {
-            case FINGERPRINT_ACQUIRED_GOOD:
+            case FINGERPRINT_ACQUIRED_GOOD, FINGERPRINT_ACQUIRED_START:
                 return null;
             case FINGERPRINT_ACQUIRED_PARTIAL:
                 return context.getString(
@@ -1546,13 +1546,10 @@
             case FINGERPRINT_ACQUIRED_VENDOR: {
                 String[] msgArray = context.getResources().getStringArray(
                         com.android.internal.R.array.fingerprint_acquired_vendor);
-                if (vendorCode < msgArray.length) {
+                if (vendorCode < msgArray.length && !msgArray[vendorCode].isEmpty()) {
                     return msgArray[vendorCode];
                 }
             }
-                break;
-            case FINGERPRINT_ACQUIRED_START:
-                return null;
         }
         Slog.w(TAG, "Invalid acquired message: " + acquireInfo + ", " + vendorCode);
         return null;
diff --git a/core/java/android/hardware/input/KeyGestureEvent.java b/core/java/android/hardware/input/KeyGestureEvent.java
index 2df5418..71d17eb 100644
--- a/core/java/android/hardware/input/KeyGestureEvent.java
+++ b/core/java/android/hardware/input/KeyGestureEvent.java
@@ -100,6 +100,7 @@
     public static final int KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT = 60;
     public static final int KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS = 61;
     public static final int KEY_GESTURE_TYPE_MOVE_TO_NEXT_DISPLAY = 62;
+    public static final int KEY_GESTURE_TYPE_TOGGLE_TALKBACK = 63;
 
     public static final int FLAG_CANCELLED = 1;
 
@@ -177,6 +178,7 @@
             KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT,
             KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS,
             KEY_GESTURE_TYPE_MOVE_TO_NEXT_DISPLAY,
+            KEY_GESTURE_TYPE_TOGGLE_TALKBACK,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface KeyGestureType {
@@ -597,6 +599,8 @@
                 return "KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT";
             case KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS:
                 return "KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS";
+            case KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
+                return "KEY_GESTURE_TYPE_TOGGLE_TALKBACK";
             default:
                 return Integer.toHexString(value);
         }
diff --git a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
index 6afb8e0..8eaadde 100644
--- a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
+++ b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
@@ -29,6 +29,8 @@
 
 import com.android.internal.annotations.GuardedBy;
 
+import dalvik.annotation.optimization.NeverCompile;
+
 import java.io.FileDescriptor;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -1331,6 +1333,7 @@
                 mMatchAllFutureMessages, true);
     }
 
+    @NeverCompile
     private void printPriorityQueueNodes() {
         Iterator<MessageNode> iterator = mPriorityQueue.iterator();
 
@@ -1342,6 +1345,7 @@
         }
     }
 
+    @NeverCompile
     private int dumpPriorityQueue(ConcurrentSkipListSet<MessageNode> queue, Printer pw,
             String prefix, Handler h, int n) {
         int count = 0;
@@ -1357,6 +1361,7 @@
         return count;
     }
 
+    @NeverCompile
     void dump(Printer pw, String prefix, Handler h) {
         long now = SystemClock.uptimeMillis();
         int n = 0;
@@ -1387,6 +1392,7 @@
                 + ", quitting=" + (boolean) sQuitting.getVolatile(this) + ")");
     }
 
+    @NeverCompile
     private int dumpPriorityQueue(ConcurrentSkipListSet<MessageNode> queue,
             ProtoOutputStream proto) {
         int count = 0;
@@ -1399,6 +1405,7 @@
         return count;
     }
 
+    @NeverCompile
     void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long messageQueueToken = proto.start(fieldId);
 
diff --git a/core/java/android/os/ITradeInMode.aidl b/core/java/android/os/ITradeInMode.aidl
new file mode 100644
index 0000000..f15954d
--- /dev/null
+++ b/core/java/android/os/ITradeInMode.aidl
@@ -0,0 +1,62 @@
+/*
+ * 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.os;
+
+/** @hide */
+interface ITradeInMode {
+    /**
+     * Enable adb in limited-privilege trade-in mode. Returns true if trade-in
+     * mode was enabled.
+     *
+     * Trade-in mode can be enabled if the following conditions are all true:
+     *   ro.debuggable is 0.
+     *   Settings.Global.ADB_ENABLED is 0.
+     *   Settings.Global.USER_SETUP_COMPLETE is 0.
+     *   Settings.Secure.DEVICE_PROVISIONED is 0.
+     *
+     * It is stopped automatically when any of the following conditions become
+     * true:
+     *
+     *   Settings.Global.USER_SETUP_COMPLETE is 1.
+     *   Settings.Secure.DEVICE_PROVISIONED is 1.
+     *   A change in network configuration occurs.
+     *   An account is added.
+     *
+     * ENTER_TRADE_IN_MODE permission is required.
+     */
+    boolean start();
+
+    /**
+     * Returns whether evaluation mode is allowed on this device. It will return
+     * false if any kind of device protection (such as FRP) is detected.
+     *
+     * ENTER_TRADE_IN_MODE permission is required.
+     */
+    boolean isEvaluationModeAllowed();
+
+    /**
+     * Enable full adb access and provision the device. This forces a factory
+     * reset on the next boot.
+     *
+     * This will return false if start() was not called, if factory reset
+     * protection is active, or if trade-in mode was disabled due to any of the
+     * conditions listed above for start().
+     *
+     * ENTER_TRADE_IN_MODE permission is required.
+     */
+    boolean enterEvaluationMode();
+}
diff --git a/core/java/android/os/LegacyMessageQueue/MessageQueue.java b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
index 4474e7e..9f7b0b7 100644
--- a/core/java/android/os/LegacyMessageQueue/MessageQueue.java
+++ b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
@@ -28,6 +28,8 @@
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 
+import dalvik.annotation.optimization.NeverCompile;
+
 import java.io.FileDescriptor;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -1106,6 +1108,7 @@
         }
     }
 
+    @NeverCompile
     void dump(Printer pw, String prefix, Handler h) {
         synchronized (this) {
             pw.println(prefix + "(MessageQueue is using Legacy implementation)");
@@ -1122,6 +1125,7 @@
         }
     }
 
+    @NeverCompile
     void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long messageQueueToken = proto.start(fieldId);
         synchronized (this) {
diff --git a/core/java/android/os/LockedMessageQueue/MessageQueue.java b/core/java/android/os/LockedMessageQueue/MessageQueue.java
index f1affce..f3eec13 100644
--- a/core/java/android/os/LockedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/LockedMessageQueue/MessageQueue.java
@@ -30,6 +30,8 @@
 
 import com.android.internal.annotations.GuardedBy;
 
+import dalvik.annotation.optimization.NeverCompile;
+
 import java.io.FileDescriptor;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -294,6 +296,7 @@
         * Keep this for manual debugging. It's easier to pepper the code with this function
         * than MessageQueue.dump()
         */
+        @NeverCompile
         void print() {
             Log.v(TAG, "heap num elem: " + mNumElements + " mHeap.length " + mHeap.length);
             for (int i = 0; i < mNumElements; i++) {
@@ -1209,6 +1212,7 @@
                 sMatchAllFutureMessages, true);
     }
 
+    @NeverCompile
     int dumpPriorityQueue(Printer pw, String prefix, Handler h, MessageHeap priorityQueue) {
         int n = 0;
         long now = SystemClock.uptimeMillis();
@@ -1222,6 +1226,7 @@
         return n;
     }
 
+    @NeverCompile
     void dumpPriorityQueue(ProtoOutputStream proto, MessageHeap priorityQueue) {
         for (int i = 0; i < priorityQueue.numElements(); i++) {
             Message m = priorityQueue.getMessageAt(i);
@@ -1229,6 +1234,7 @@
         }
     }
 
+    @NeverCompile
     void dump(Printer pw, String prefix, Handler h) {
         synchronized (this) {
             pw.println(prefix + "(MessageQueue is using Locked implementation)");
@@ -1240,6 +1246,7 @@
         }
     }
 
+    @NeverCompile
     void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long messageQueueToken = proto.start(fieldId);
         synchronized (this) {
diff --git a/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java
index 02335972..db323dc 100644
--- a/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java
+++ b/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java
@@ -29,6 +29,8 @@
 
 import com.android.internal.annotations.GuardedBy;
 
+import dalvik.annotation.optimization.NeverCompile;
+
 import java.io.FileDescriptor;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -1249,6 +1251,7 @@
                 mMatchAllFutureMessages, true);
     }
 
+    @NeverCompile
     private void printPriorityQueueNodes() {
         Iterator<MessageNode> iterator = mPriorityQueue.iterator();
 
@@ -1260,6 +1263,7 @@
         }
     }
 
+    @NeverCompile
     private int dumpPriorityQueue(PriorityQueue<MessageNode> queue, Printer pw, String prefix,
             Handler h, int n) {
         int count = 0;
@@ -1275,6 +1279,7 @@
         return count;
     }
 
+    @NeverCompile
     void dump(Printer pw, String prefix, Handler h) {
         long now = SystemClock.uptimeMillis();
         int n = 0;
@@ -1307,6 +1312,7 @@
                 + ", quitting=" + (boolean) sQuitting.getVolatile(this) + ")");
     }
 
+    @NeverCompile
     private int dumpPriorityQueue(PriorityQueue<MessageNode> queue, ProtoOutputStream proto) {
         int count = 0;
 
@@ -1318,6 +1324,7 @@
         return count;
     }
 
+    @NeverCompile
     void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long messageQueueToken = proto.start(fieldId);
 
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index c7cc653..9c83bc2 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -91,6 +91,14 @@
 }
 
 flag {
+    name: "allow_thermal_thresholds_callback"
+    is_exported: true
+    namespace: "game"
+    description: "Enable thermal threshold callback"
+    bug: "360486877"
+}
+
+flag {
     name: "android_os_build_vanilla_ice_cream"
     is_exported: true
     namespace: "build"
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index bfefba5b..3df7ff9 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -282,3 +282,12 @@
     description: "This fixed read-only flag is used to enable platform support for Skin Temperature."
     bug: "369872443"
 }
+
+flag {
+    name: "platform_oxygen_saturation_enabled"
+    is_fixed_read_only: true
+    is_exported: true
+    namespace: "android_health_services"
+    description: "This fixed read-only flag is used to enable platform support for Oxygen Saturation (SpO2)."
+    bug: "369873227"
+}
diff --git a/core/java/android/print/IPrintDocumentAdapter.aidl b/core/java/android/print/IPrintDocumentAdapter.aidl
index 8f33e0b..9d384fb 100644
--- a/core/java/android/print/IPrintDocumentAdapter.aidl
+++ b/core/java/android/print/IPrintDocumentAdapter.aidl
@@ -37,5 +37,4 @@
     void write(in PageRange[] pages, in ParcelFileDescriptor fd,
             IWriteResultCallback callback, int sequence);
     void finish();
-    void kill(String reason);
 }
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index ef274a5..1b1554f 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -946,17 +946,6 @@
         }
 
         @Override
-        public void kill(String reason) {
-            synchronized (mLock) {
-                // If destroyed the handler is null.
-                if (!isDestroyedLocked()) {
-                    mHandler.obtainMessage(MyHandler.MSG_ON_KILL,
-                            reason).sendToTarget();
-                }
-            }
-        }
-
-        @Override
         public void onActivityPaused(Activity activity) {
             /* do nothing */
         }
@@ -1118,15 +1107,6 @@
                         }
                     } break;
 
-                    case MSG_ON_KILL: {
-                        if (DEBUG) {
-                            Log.i(LOG_TAG, "onKill()");
-                        }
-
-                        String reason = (String) message.obj;
-                        throw new RuntimeException(reason);
-                    }
-
                     default: {
                         throw new IllegalArgumentException("Unknown message: "
                                 + message.what);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 764570e..83c599e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5472,6 +5472,14 @@
         public static final String VOLUME_MASTER = "volume_master";
 
         /**
+         * The mapping of input device to its input gain index.
+         *
+         * @hide
+         */
+        @Readable
+        public static final String INPUT_GAIN_INDEX_SETTINGS = "input_gain_index_settings";
+
+        /**
          * Master mono (int 1 = mono, 0 = normal).
          *
          * @hide
@@ -8390,7 +8398,6 @@
         @Readable
         public static final String LOCK_SCREEN_LOCK_AFTER_TIMEOUT = "lock_screen_lock_after_timeout";
 
-
         /**
          * This preference contains the string that shows for owner info on LockScreen.
          * @hide
@@ -11281,7 +11288,8 @@
                 "assist_long_press_home_enabled";
 
         /**
-         * Whether all entrypoints can trigger search. Replaces individual settings.
+         * Whether all entrypoints (e.g. long-press home, long-press nav handle)
+         * can trigger contextual search.
          *
          * @hide
          */
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 396be7b..03f9d98 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -18,9 +18,11 @@
 
 import static android.system.OsConstants.EINVAL;
 
+import android.annotation.FlaggedApi;
 import android.annotation.FloatRange;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.SuppressLint;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.pm.ActivityInfo;
 import android.content.res.CompatibilityInfo.Translator;
@@ -1026,6 +1028,211 @@
     }
 
     /**
+     * Parameter object for {@link #setFrameRate(FrameRateParams)}, describing the intended frame
+     * rate for the Surface that setFrameRate is called on.
+     */
+    @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+    public static class FrameRateParams {
+        private FrameRateParams() {}
+
+        /**
+         * A static FrameRateParams that can be passed directly into {@link
+         * #setFrameRate(FrameRateParams)} to indicate the surface has no preference and any frame
+         * rate is acceptable.
+         */
+        @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+        public static final FrameRateParams IGNORE =
+                new FrameRateParams.Builder().setDesiredRateRange(0f, Float.MAX_VALUE).build();
+
+        @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+        public static final class Builder {
+            private float mDesiredMinRate;
+            private float mDesiredMaxRate;
+            private float mFixedSourceRate;
+            private int mChangeFrameRateStrategy;
+
+            /**
+             * Sets the desired frame rate range (inclusive) values for the surface, specifying that
+             * the surface prefers the device render rate to be in the range [desiredMinRate,
+             * desiredMaxRate].
+
+             * Set desiredMaxRate to FLOAT.MAX_VALUE to indicate the surface prefers any value
+             * greater than or equal to desiredMinRate.
+             *
+             * Set desiredMinRate = desiredMaxRate to indicate the surface prefers an exact frame
+             * rate. Note that this is different than specifying the fixed source frame rate with
+             * {@link FrameRateParams.Builder#setFixedSourceRate}. To reiterate, this call is used
+             * to specify the surface's frame rate preference to be within the desired range.
+             *
+             * desiredMaxRate must be greater than or equal to desiredMinRate.
+             * The values should be greater than or equal to 0.
+             *
+             * If the surface has no preference and any frame rate is acceptable, use the constant
+             * {@link FrameRateParams.IGNORE} in {@link #setFrameRate(FrameRateParams)} instead of
+             * building {@link FrameRateParams.Builder}.
+             *
+             * @see FrameRateParams#getDesiredMinRate()
+             * @see FrameRateParams#getDesiredMaxRate()
+             */
+            @SuppressLint("MissingGetterMatchingBuilder")
+            @NonNull
+            @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+            public Builder setDesiredRateRange(@FloatRange(from = 0.0) float desiredMinRate,
+                    @FloatRange(from = 0.0) float desiredMaxRate) {
+                if (desiredMaxRate < desiredMinRate) {
+                    Log.e(TAG,
+                            "Failed to set desired frame rate range. desiredMaxRate should be "
+                                    + "greater than or equal to desiredMinRate");
+                    return this;
+                }
+                mDesiredMinRate = desiredMinRate;
+                mDesiredMaxRate = desiredMaxRate;
+                return this;
+            }
+
+            /**
+             * Sets the fixed frame rate of the surface when its content has a fixed frame rate,
+             * e.g. a video with a fixed frame rate.
+             *
+             * When the frame rate chosen for the surface is the {@code fixedSourceRate} or a
+             * multiple, the surface can render without frame pulldown, for optimal smoothness. For
+             * example, a 30 fps video ({@code fixedSourceRate=30}) renders just as well on 30 fps,
+             * 60 fps, 90 fps, 120 fps, and so on.
+             *
+             * This method to set the fixed source rate can also be used together with a desired
+             * frame rate range via {@link FrameRateParams.Builder#setDesiredRateRange}. This still
+             * means the surface's content has a fixed frame rate of the provided {@code
+             * fixedSourceRate}, as well as it preferring to be within the desired frame rate range.
+             * For example, a 30 fps video {@code fixedSourceRate=30} and desired frame rate range
+             * [60,90] means the surface ideally prefers 60 fps (which is 30 fps * 2) or 90 fps (30
+             * fps * 3).
+             *
+             * @see FrameRateParams#getFixedSourceRate()
+             */
+            @NonNull
+            @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+            public Builder setFixedSourceRate(@FloatRange(from = 0.0) float fixedSourceRate) {
+                mFixedSourceRate = fixedSourceRate;
+                return this;
+            }
+
+            /**
+             * Whether display refresh rate transitions caused by this surface should be seamless. A
+             * seamless transition is one that doesn't have any visual interruptions, such as a
+             * black screen for a second or two. Value is
+             * Surface.CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, or Surface.CHANGE_FRAME_RATE_ALWAYS
+             *
+             * @see FrameRateParams#getChangeFrameRateStrategy()
+             */
+            @NonNull
+            @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+            public Builder setChangeFrameRateStrategy(
+                    @ChangeFrameRateStrategy int changeFrameRateStrategy) {
+                mChangeFrameRateStrategy = changeFrameRateStrategy;
+                return this;
+            }
+
+            /**
+             * Builds the FrameRateParams object.
+             */
+            @NonNull
+            @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+            public FrameRateParams build() {
+                FrameRateParams frameRate = new FrameRateParams();
+                frameRate.mDesiredMinRate = this.mDesiredMinRate;
+                frameRate.mDesiredMaxRate = this.mDesiredMaxRate;
+                frameRate.mFixedSourceRate = this.mFixedSourceRate;
+                frameRate.mChangeFrameRateStrategy = this.mChangeFrameRateStrategy;
+                return frameRate;
+            }
+        }
+
+        /**
+         * Gets the minimum desired frame rate.
+         * @see FrameRateParams.Builder#setDesiredRateRange()
+         */
+        @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+        public float getDesiredMinRate() {
+            return mDesiredMinRate;
+        }
+
+        /**
+         * Gets the maximum desired frame rate.
+         * @see FrameRateParams.Builder#setDesiredRateRange()
+         */
+        @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+        public float getDesiredMaxRate() {
+            return mDesiredMaxRate;
+        }
+
+        /**
+         * Gets the fixed source frame rate.
+         * @see FrameRateParams.Builder#setFixedSourceRate()
+         */
+        @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+        public float getFixedSourceRate() {
+            return mFixedSourceRate;
+        }
+
+        /**
+         * Gets the strategy when changing frame rate.
+         * @see FrameRateParams.Builder#setChangeFrameRateStrategy
+         */
+        @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+        @ChangeFrameRateStrategy
+        public int getChangeFrameRateStrategy() {
+            return mChangeFrameRateStrategy;
+        }
+
+        float mDesiredMinRate;
+        float mDesiredMaxRate;
+        float mFixedSourceRate;
+        int mChangeFrameRateStrategy;
+    }
+
+    /**
+     * Sets the intended frame rate for this surface.
+     *
+     * <p>On devices that are capable of running the display at different frame rates,
+     * the system may choose a display refresh rate to better match this surface's frame
+     * rate. Usage of this API won't introduce frame rate throttling, or affect other
+     * aspects of the application's frame production pipeline. However, because the system
+     * may change the display refresh rate, calls to this function may result in changes
+     * to Choreographer callback timings, and changes to the time interval at which the
+     * system releases buffers back to the application.</p>
+     *
+     * <p>Note that this only has an effect for surfaces presented on the display. If this
+     * surface is consumed by something other than the system compositor, e.g. a media
+     * codec, this call has no effect.</p>
+     *
+     * @param frameRateParams The parameters describing the intended frame rate of this surface.
+     *         Refer to {@link FrameRateParams} for details.
+     * @throws IllegalArgumentException If <code>frameRateParams</code> is invalid.
+     * @see #clearFrameRate()
+     */
+    @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_API)
+    public void setFrameRate(@NonNull FrameRateParams frameRateParams) {
+        synchronized (mLock) {
+            checkNotReleasedLocked();
+            // TODO(b/362798998): Logic currently incomplete: it uses fixed source rate over the
+            // desired min/max rates. Fix when plumbing is upgraded.
+            int compatibility = frameRateParams.getFixedSourceRate() == 0
+                    ? FRAME_RATE_COMPATIBILITY_DEFAULT
+                    : FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
+            float frameRate = compatibility == FRAME_RATE_COMPATIBILITY_DEFAULT
+                    ? frameRateParams.getDesiredMinRate()
+                    : frameRateParams.getFixedSourceRate();
+            int error = nativeSetFrameRate(mNativeObject, frameRate, compatibility,
+                    frameRateParams.getChangeFrameRateStrategy());
+            if (error == -EINVAL) {
+                throw new IllegalArgumentException("Invalid argument to Surface.setFrameRate()");
+            } else if (error != 0) {
+                Log.e(TAG, "Failed to set frame rate on Surface. Native error: " + error);
+            }
+        }
+    }
+
+    /**
      * Sets the intended frame rate for this surface.
      *
      * <p>On devices that are capable of running the display at different refresh rates,
diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java
index d90455a..2ca62a0 100644
--- a/core/java/android/view/inputmethod/ImeTracker.java
+++ b/core/java/android/view/inputmethod/ImeTracker.java
@@ -220,6 +220,7 @@
             PHASE_WM_POSTING_CHANGED_IME_VISIBILITY,
             PHASE_WM_INVOKING_IME_REQUESTED_LISTENER,
             PHASE_CLIENT_ALREADY_HIDDEN,
+            PHASE_CLIENT_VIEW_HANDLER_AVAILABLE,
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface Phase {}
@@ -424,6 +425,11 @@
             ImeProtoEnums.PHASE_WM_INVOKING_IME_REQUESTED_LISTENER;
     /** IME is requested to be hidden, but already hidden. Don't hide to avoid another animation. */
     int PHASE_CLIENT_ALREADY_HIDDEN = ImeProtoEnums.PHASE_CLIENT_ALREADY_HIDDEN;
+    /**
+     * The view's handler is needed to check if we're running on a different thread. We can't
+     * continue without.
+     */
+    int PHASE_CLIENT_VIEW_HANDLER_AVAILABLE = ImeProtoEnums.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE;
 
     /**
      * Called when an IME request is started.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 47fc437..2d2f4c9 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -2557,21 +2557,24 @@
     public boolean hideSoftInputFromWindow(IBinder windowToken, @HideFlags int flags,
             ResultReceiver resultReceiver) {
         return hideSoftInputFromWindow(windowToken, flags, resultReceiver,
-                SoftInputShowHideReason.HIDE_SOFT_INPUT);
+                SoftInputShowHideReason.HIDE_SOFT_INPUT, null);
     }
 
     private boolean hideSoftInputFromWindow(IBinder windowToken, @HideFlags int flags,
-            ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
+            ResultReceiver resultReceiver, @SoftInputShowHideReason int reason,
+            @Nullable ImeTracker.Token statsToken) {
         // Get served view initially for statsToken creation.
         final View initialServedView;
         synchronized (mH) {
             initialServedView = getServedViewLocked();
         }
 
-        final var statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
-                ImeTracker.ORIGIN_CLIENT, reason, ImeTracker.isFromUser(initialServedView));
-        ImeTracker.forLatency().onRequestHide(statsToken,
-                ImeTracker.ORIGIN_CLIENT, reason, ActivityThread::currentApplication);
+        if (statsToken == null) {
+            statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
+                    ImeTracker.ORIGIN_CLIENT, reason, ImeTracker.isFromUser(initialServedView));
+            ImeTracker.forLatency().onRequestHide(statsToken, ImeTracker.ORIGIN_CLIENT, reason,
+                    ActivityThread::currentApplication);
+        }
         ImeTracing.getInstance().triggerClientDump("InputMethodManager#hideSoftInputFromWindow",
                 this, null /* icProto */);
         checkFocus();
@@ -2591,6 +2594,17 @@
                 // TODO(b/322992891) handle case of HIDE_IMPLICIT_ONLY
                 final var viewRootImpl = servedView.getViewRootImpl();
                 if (viewRootImpl != null) {
+                    Handler vh = servedView.getHandler();
+                    if (vh == null) {
+                        // If the view doesn't have a handler, something has changed out from
+                        // under us. The current input has been closed before (from checkFocus).
+                        ImeTracker.forLogging().onFailed(statsToken,
+                                ImeTracker.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE);
+                        return false;
+                    }
+                    ImeTracker.forLogging().onProgress(statsToken,
+                            ImeTracker.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE);
+
                     if (resultReceiver != null) {
                         final boolean imeReqVisible =
                                 (viewRootImpl.getInsetsController().getRequestedVisibleTypes()
@@ -2599,7 +2613,15 @@
                                 !imeReqVisible ? InputMethodManager.RESULT_UNCHANGED_HIDDEN
                                         : InputMethodManager.RESULT_HIDDEN, null);
                     }
-                    viewRootImpl.getInsetsController().hide(WindowInsets.Type.ime());
+                    if (vh.getLooper() != Looper.myLooper()) {
+                        // The view is running on a different thread than our own, so
+                        // we need to reschedule our work for over there.
+                        if (DEBUG) Log.v(TAG, "Hiding soft input: reschedule to view thread");
+                        vh.post(() -> viewRootImpl.getInsetsController().hide(
+                                WindowInsets.Type.ime()));
+                    } else {
+                        viewRootImpl.getInsetsController().hide(WindowInsets.Type.ime());
+                    }
                 }
                 return true;
             } else {
@@ -2646,8 +2668,14 @@
 
             ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
 
-            return IInputMethodManagerGlobalInvoker.hideSoftInput(mClient, view.getWindowToken(),
-                    statsToken, flags, null, reason, mAsyncShowHideMethodEnabled);
+            if (Flags.refactorInsetsController()) {
+                return hideSoftInputFromWindow(view.getWindowToken(), flags,
+                        null /* resultReceiver */, reason, statsToken);
+            } else {
+                return IInputMethodManagerGlobalInvoker.hideSoftInput(mClient,
+                        view.getWindowToken(), statsToken, flags, null, reason,
+                        mAsyncShowHideMethodEnabled);
+            }
         }
     }
 
@@ -3143,7 +3171,7 @@
                 if (rootInsets != null && rootInsets.isVisible(WindowInsets.Type.ime())) {
                     hideSoftInputFromWindow(view.getWindowToken(), hideFlags,
                             null /* resultReceiver */,
-                            SoftInputShowHideReason.HIDE_TOGGLE_SOFT_INPUT);
+                            SoftInputShowHideReason.HIDE_TOGGLE_SOFT_INPUT, null);
                 } else {
                     showSoftInput(view, showFlags, null /* resultReceiver */,
                             SoftInputShowHideReason.SHOW_TOGGLE_SOFT_INPUT);
@@ -3721,14 +3749,19 @@
 
             ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
 
-            IInputMethodManagerGlobalInvoker.hideSoftInput(
-                    mClient,
-                    rootView.getWindowToken(),
-                    statsToken,
-                    HIDE_NOT_ALWAYS,
-                    null,
-                    reason,
-                    true /*async */);
+            if (Flags.refactorInsetsController()) {
+                mCurRootView.getInsetsController().hide(WindowInsets.Type.ime(),
+                        false /* fromIme */, statsToken);
+            } else {
+                IInputMethodManagerGlobalInvoker.hideSoftInput(
+                        mClient,
+                        rootView.getWindowToken(),
+                        statsToken,
+                        HIDE_NOT_ALWAYS,
+                        null,
+                        reason,
+                        true /*async */);
+            }
         }
     }
 
diff --git a/core/java/android/window/BackEvent.java b/core/java/android/window/BackEvent.java
index 90fac361..1b9235b 100644
--- a/core/java/android/window/BackEvent.java
+++ b/core/java/android/window/BackEvent.java
@@ -58,7 +58,7 @@
     private final float mTouchX;
     private final float mTouchY;
     private final float mProgress;
-    private final long mFrameTime;
+    private final long mFrameTimeMillis;
 
     @SwipeEdge
     private final int mSwipeEdge;
@@ -68,7 +68,7 @@
         if (predictiveBackTimestampApi()) {
             return new BackEvent(backMotionEvent.getTouchX(), backMotionEvent.getTouchY(),
                     backMotionEvent.getProgress(), backMotionEvent.getSwipeEdge(),
-                    backMotionEvent.getFrameTime());
+                    backMotionEvent.getFrameTimeMillis());
         } else {
             return new BackEvent(backMotionEvent.getTouchX(), backMotionEvent.getTouchY(),
                     backMotionEvent.getProgress(), backMotionEvent.getSwipeEdge());
@@ -88,7 +88,7 @@
         mTouchY = touchY;
         mProgress = progress;
         mSwipeEdge = swipeEdge;
-        mFrameTime = System.nanoTime() / TimeUtils.NANOS_PER_MS;
+        mFrameTimeMillis = System.nanoTime() / TimeUtils.NANOS_PER_MS;
     }
 
     /**
@@ -98,16 +98,16 @@
      * @param touchY Absolute Y location of the touch point of this event.
      * @param progress Value between 0 and 1 on how far along the back gesture is.
      * @param swipeEdge Indicates which edge the swipe starts from.
-     * @param frameTime frame time of the back event.
+     * @param frameTimeMillis frame time of the back event.
      */
     @FlaggedApi(FLAG_PREDICTIVE_BACK_TIMESTAMP_API)
     public BackEvent(float touchX, float touchY, float progress, @SwipeEdge int swipeEdge,
-            long frameTime) {
+            long frameTimeMillis) {
         mTouchX = touchX;
         mTouchY = touchY;
         mProgress = progress;
         mSwipeEdge = swipeEdge;
-        mFrameTime = frameTime;
+        mFrameTimeMillis = frameTimeMillis;
     }
 
     /**
@@ -160,8 +160,8 @@
      * Returns the frameTime of the BackEvent in milliseconds. Useful for calculating velocity.
      */
     @FlaggedApi(FLAG_PREDICTIVE_BACK_TIMESTAMP_API)
-    public long getFrameTime() {
-        return mFrameTime;
+    public long getFrameTimeMillis() {
+        return mFrameTimeMillis;
     }
 
     @Override
@@ -177,7 +177,7 @@
                 && mTouchY == that.mTouchY
                 && mProgress == that.mProgress
                 && mSwipeEdge == that.mSwipeEdge
-                && mFrameTime == that.mFrameTime;
+                && mFrameTimeMillis == that.mFrameTimeMillis;
     }
 
     @Override
@@ -187,7 +187,7 @@
                 + ", mTouchY=" + mTouchY
                 + ", mProgress=" + mProgress
                 + ", mSwipeEdge=" + mSwipeEdge
-                + ", mFrameTime=" + mFrameTime + "ms"
+                + ", mFrameTimeMillis=" + mFrameTimeMillis
                 + "}";
     }
 }
diff --git a/core/java/android/window/BackMotionEvent.java b/core/java/android/window/BackMotionEvent.java
index a8ec4ee..cc2afbc 100644
--- a/core/java/android/window/BackMotionEvent.java
+++ b/core/java/android/window/BackMotionEvent.java
@@ -33,7 +33,7 @@
 public final class BackMotionEvent implements Parcelable {
     private final float mTouchX;
     private final float mTouchY;
-    private final long mFrameTime;
+    private final long mFrameTimeMillis;
     private final float mProgress;
     private final boolean mTriggerBack;
 
@@ -49,7 +49,7 @@
      *
      * @param touchX Absolute X location of the touch point of this event.
      * @param touchY Absolute Y location of the touch point of this event.
-     * @param frameTime Event time of the corresponding touch event.
+     * @param frameTimeMillis Event time of the corresponding touch event.
      * @param progress Value between 0 and 1 on how far along the back gesture is.
      * @param triggerBack Indicates whether the back arrow is in the triggered state or not
      * @param swipeEdge Indicates which edge the swipe starts from.
@@ -59,14 +59,14 @@
     public BackMotionEvent(
             float touchX,
             float touchY,
-            long frameTime,
+            long frameTimeMillis,
             float progress,
             boolean triggerBack,
             @BackEvent.SwipeEdge int swipeEdge,
             @Nullable RemoteAnimationTarget departingAnimationTarget) {
         mTouchX = touchX;
         mTouchY = touchY;
-        mFrameTime = frameTime;
+        mFrameTimeMillis = frameTimeMillis;
         mProgress = progress;
         mTriggerBack = triggerBack;
         mSwipeEdge = swipeEdge;
@@ -80,7 +80,7 @@
         mTriggerBack = in.readBoolean();
         mSwipeEdge = in.readInt();
         mDepartingAnimationTarget = in.readTypedObject(RemoteAnimationTarget.CREATOR);
-        mFrameTime = in.readLong();
+        mFrameTimeMillis = in.readLong();
     }
 
     @NonNull
@@ -109,7 +109,7 @@
         dest.writeBoolean(mTriggerBack);
         dest.writeInt(mSwipeEdge);
         dest.writeTypedObject(mDepartingAnimationTarget, flags);
-        dest.writeLong(mFrameTime);
+        dest.writeLong(mFrameTimeMillis);
     }
 
     /**
@@ -156,8 +156,8 @@
     /**
      * Returns the frame time of the BackMotionEvent in milliseconds.
      */
-    public long getFrameTime() {
-        return mFrameTime;
+    public long getFrameTimeMillis() {
+        return mFrameTimeMillis;
     }
 
     /**
@@ -175,7 +175,7 @@
         return "BackMotionEvent{"
                 + "mTouchX=" + mTouchX
                 + ", mTouchY=" + mTouchY
-                + ", mFrameTime=" + mFrameTime + "ms"
+                + ", mFrameTimeMillis=" + mFrameTimeMillis
                 + ", mProgress=" + mProgress
                 + ", mTriggerBack=" + mTriggerBack
                 + ", mSwipeEdge=" + mSwipeEdge
diff --git a/core/java/android/window/BackTouchTracker.java b/core/java/android/window/BackTouchTracker.java
index 39a3025..4908068 100644
--- a/core/java/android/window/BackTouchTracker.java
+++ b/core/java/android/window/BackTouchTracker.java
@@ -151,7 +151,7 @@
         return new BackMotionEvent(
                 /* touchX = */ mInitTouchX,
                 /* touchY = */ mInitTouchY,
-                /* frameTime = */ 0,
+                /* frameTimeMillis = */ 0,
                 /* progress = */ 0,
                 /* triggerBack = */ mTriggerBack,
                 /* swipeEdge = */ mSwipeEdge,
@@ -236,7 +236,7 @@
         return new BackMotionEvent(
                 /* touchX = */ mLatestTouchX,
                 /* touchY = */ mLatestTouchY,
-                /* frameTime = */ 0,
+                /* frameTimeMillis = */ 0,
                 /* progress = */ progress,
                 /* triggerBack = */ mTriggerBack,
                 /* swipeEdge = */ mSwipeEdge,
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index 8db1f95..bd01899 100644
--- a/core/java/android/window/ImeOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -238,7 +238,7 @@
             try {
                 long frameTime = 0;
                 if (predictiveBackTimestampApi()) {
-                    frameTime = backEvent.getFrameTime();
+                    frameTime = backEvent.getFrameTimeMillis();
                 }
                 mIOnBackInvokedCallback.onBackStarted(
                         new BackMotionEvent(backEvent.getTouchX(), backEvent.getTouchY(), frameTime,
@@ -254,7 +254,7 @@
             try {
                 long frameTime = 0;
                 if (predictiveBackTimestampApi()) {
-                    frameTime = backEvent.getFrameTime();
+                    frameTime = backEvent.getFrameTimeMillis();
                 }
                 mIOnBackInvokedCallback.onBackProgressed(
                         new BackMotionEvent(backEvent.getTouchX(), backEvent.getTouchY(), frameTime,
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 0bcc9c1..a0d58d5 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -348,3 +348,10 @@
     description: "Enables a switch to change the concequence of dragging a window to the top edge."
     bug: "372614715"
 }
+
+flag {
+    name: "enable_task_resizing_keyboard_shortcuts"
+    namespace: "lse_desktop_experience"
+    description: "Enables keyboard shortcuts for resizing tasks in desktop mode."
+    bug: "335819608"
+}
diff --git a/core/java/com/android/internal/widget/floatingtoolbar/OWNERS b/core/java/com/android/internal/widget/floatingtoolbar/OWNERS
index ed9425c..999ea0e 100644
--- a/core/java/com/android/internal/widget/floatingtoolbar/OWNERS
+++ b/core/java/com/android/internal/widget/floatingtoolbar/OWNERS
@@ -1 +1 @@
-include /core/java/android/view/selectiontoolbar/OWNERS
+include /core/java/android/permission/OWNERS
diff --git a/core/res/Android.bp b/core/res/Android.bp
index aa324fc..f6ca821 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -158,6 +158,7 @@
     flags_packages: [
         "android.app.appfunctions.flags-aconfig",
         "android.app.contextualsearch.flags-aconfig",
+        "android.appwidget.flags-aconfig",
         "android.content.pm.flags-aconfig",
         "android.provider.flags-aconfig",
         "camera_platform_flags",
@@ -169,6 +170,7 @@
         "android.media.tv.flags-aconfig",
         "android.security.flags-aconfig",
         "com.android.hardware.input.input-aconfig",
+        "aconfig_trade_in_mode_flags",
     ],
 }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6ab6476..fb06e96 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1494,8 +1494,8 @@
             android:description="@string/permdesc_readBasicPhoneState"
             android:protectionLevel="normal" />
 
-    <!-- Allows read access to the device's phone number(s). This is a subset of the capabilities
-         granted by {@link #READ_PHONE_STATE} but is exposed to instant applications.
+    <!-- Allows read access to the device's phone number(s),
+         which is exposed to instant applications.
          <p>Protection level: dangerous-->
     <permission android:name="android.permission.READ_PHONE_NUMBERS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -8464,6 +8464,14 @@
     <permission android:name="android.permission.SETUP_FSVERITY"
                 android:protectionLevel="signature|privileged"/>
 
+    <!-- Allows app to enter trade-in-mode.
+        <p>Protection level: signature|privileged
+        @hide
+    -->
+    <permission android:name="android.permission.ENTER_TRADE_IN_MODE"
+                android:protectionLevel="signature|privileged"
+                android:featureFlag="com.android.tradeinmode.flags.enable_trade_in_mode" />
+
     <!--
         @TestApi
         Signature permission reserved for testing. This should never be used to
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index ad8f056..ad0809f 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -678,8 +678,8 @@
     <string name="fingerprint_error_timeout" msgid="7361192266621252164">"مهلت تنظیم اثر انگشت به‌پایان رسید. دوباره امتحان کنید."</string>
     <string name="fingerprint_error_canceled" msgid="5541771463159727513">"عملکرد اثر انگشت لغو شد"</string>
     <string name="fingerprint_error_user_canceled" msgid="2017941773466506863">"کاربر عملیات اثر انگشت را لغو کرد"</string>
-    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"تلاش‌ها از حد مجاز بیشتر شده است. به‌جای آن از قفل صفحه استفاده کنید."</string>
-    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"تلاش‌های بیش‌ازحد. حالا از قفل صفحه استفاده کنید."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"تلاش‌های بسیار زیاد ناموفق. به‌جای آن، از قفل صفحه استفاده کنید."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"تلاش‌های بسیار زیاد ناموفق. حالا از قفل صفحه استفاده کنید."</string>
     <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"اثر انگشت پردازش نشد. دوباره امتحان کنید."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="3144806556204061862">"اثر انگشتی ثبت نشده است"</string>
     <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"این دستگاه حسگر اثر انگشت ندارد"</string>
@@ -740,9 +740,9 @@
     <string name="face_error_no_space" msgid="5649264057026021723">"داده‌ چهره جدید ذخیره نشد. اول داده‌ چهره قدیمی را حذف کنید."</string>
     <string name="face_error_canceled" msgid="2164434737103802131">"عملیات شناسایی چهره لغو شد."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"کاربر «قفل‌گشایی با چهره» را لغو کرد"</string>
-    <string name="face_error_lockout" msgid="7864408714994529437">"تعداد زیادی تلاش ناموفق. بعداً دوباره امتحان کنید."</string>
-    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"تعداد تلاش‌ها از حد مجاز بیشتر شده است. قفل‌گشایی با چهره دردسترس نیست."</string>
-    <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"تلاش‌ها بیش از حدمجاز شده است. درعوض قفل صفحه را وارد کنید."</string>
+    <string name="face_error_lockout" msgid="7864408714994529437">"تلاش‌های بسیار زیاد ناموفق. بعداً دوباره امتحان کنید."</string>
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"تلاش‌های بسیار زیاد ناموفق. قفل‌گشایی با چهره دردسترس نیست."</string>
+    <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"تلاش‌های بسیار زیاد ناموفق. درعوض، قفل صفحه را وارد کنید."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"چهره تأیید نشد. دوباره امتحان کنید."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"«قفل‌گشایی با چهره» را راه‌اندازی نکرده‌اید"</string>
     <string name="face_error_hw_not_present" msgid="7940978724978763011">"از «قفل‌گشایی با چهره» در این دستگاه پشتیبانی نمی‌شود"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index df7006a..41f2de0 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -234,7 +234,7 @@
     <string name="turn_on_radio" msgid="2961717788170634233">"បើក​បណ្ដាញ​ឥត​ខ្សែ"</string>
     <string name="turn_off_radio" msgid="7222573978109933360">"បិទ​បណ្ដាញ​ឥតខ្សែ"</string>
     <string name="screen_lock" msgid="2072642720826409809">"ចាក់​សោ​អេក្រង់"</string>
-    <string name="power_off" msgid="4111692782492232778">"បិទ"</string>
+    <string name="power_off" msgid="4111692782492232778">"បិទថាមពល"</string>
     <string name="silent_mode_silent" msgid="5079789070221150912">"បិទ​កម្ម​វិធី​រោទ៍"</string>
     <string name="silent_mode_vibrate" msgid="8821830448369552678">"កម្មវិធី​រោទ៍​ញ័រ"</string>
     <string name="silent_mode_ring" msgid="6039011004781526678">"បើក​កម្មវិធី​រោទ៍"</string>
@@ -258,11 +258,11 @@
     <string name="global_actions" product="tv" msgid="3871763739487450369">"ជម្រើស Android TV"</string>
     <string name="global_actions" product="default" msgid="6410072189971495460">"ជម្រើស​ទូរស័ព្ទ"</string>
     <string name="global_action_lock" msgid="6949357274257655383">"ចាក់​សោ​អេក្រង់"</string>
-    <string name="global_action_power_off" msgid="4404936470711393203">"បិទ"</string>
+    <string name="global_action_power_off" msgid="4404936470711393203">"បិទថាមពល"</string>
     <string name="global_action_power_options" msgid="1185286119330160073">"ថាមពល"</string>
     <string name="global_action_restart" msgid="4678451019561687074">"ចាប់ផ្ដើមឡើងវិញ"</string>
     <string name="global_action_emergency" msgid="1387617624177105088">"អាសន្ន"</string>
-    <string name="global_action_bug_report" msgid="5127867163044170003">"របាយការណ៍​កំហុស"</string>
+    <string name="global_action_bug_report" msgid="5127867163044170003">"របាយការណ៍អំពីបញ្ហា"</string>
     <string name="global_action_logout" msgid="6093581310002476511">"បញ្ចប់​សម័យ"</string>
     <string name="global_action_screenshot" msgid="2610053466156478564">"រូបថតអេក្រង់"</string>
     <string name="bugreport_title" msgid="8549990811777373050">"របាយការណ៍អំពីបញ្ហា"</string>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 9854030..b5892f6 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -460,4 +460,16 @@
     <integer name="config_satellite_location_query_throttle_interval_minutes">10</integer>
     <java-symbol type="integer" name="config_satellite_location_query_throttle_interval_minutes" />
 
+    <!-- Boolean indicating whether to enable MT SMS polling for NB IOT NTN. -->
+    <bool name="config_enabled_mt_sms_polling">true</bool>
+    <java-symbol type="bool" name="config_enabled_mt_sms_polling" />
+
+    <!-- Text to be used for MT SMS polling in NB IOT NTN. -->
+    <string name="config_mt_sms_polling_text" translatable="false">DU\\\#MMYSM€S2BIG\\\#NORED\\\!</string>
+    <java-symbol type="string" name="config_mt_sms_polling_text" />
+
+    <!-- The time duration in millis after which Telephony can send another MT SMS polling for NB IOT NTN -->
+    <integer name="config_mt_sms_polling_throttle_millis">300000</integer>
+    <java-symbol type="integer" name="config_mt_sms_polling_throttle_millis" />
+
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 7184d9a..522dcfa 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -17,7 +17,7 @@
 ** limitations under the License.
 */
 -->
-<resources>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- The width that is used when creating thumbnails of applications. -->
     <dimen name="thumbnail_width">192dp</dimen>
     <!-- The height that is used when creating thumbnails of applications. -->
@@ -1037,9 +1037,12 @@
     <dimen name="controls_thumbnail_image_max_width">280dp</dimen>
 
     <!-- System-provided radius for the background view of app widgets. The resolved value of this resource may change at runtime. -->
-    <dimen name="system_app_widget_background_radius">28dp</dimen>
-    <!-- System-provided radius for inner views on app widgets. The resolved value of this resource may change at runtime. -->
-    <dimen name="system_app_widget_inner_radius">20dp</dimen>
+    <dimen name="system_app_widget_background_radius" android:featureFlag="!android.appwidget.flags.use_smaller_app_widget_radius">28dp</dimen>
+    <dimen name="system_app_widget_background_radius" android:featureFlag="android.appwidget.flags.use_smaller_app_widget_radius">24dp</dimen>
+    <!-- System-provided radius for inner views on app widgets that are positioned 8dp within the widget background view. The resolved value of this resource may change at runtime. -->
+    <dimen name="system_app_widget_inner_radius" android:featureFlag="!android.appwidget.flags.use_smaller_app_widget_radius">20dp</dimen>
+    <!-- System-provided radius for inner views on app widgets that are positioned 8dp within the widget background view. The resolved value of this resource may change at runtime. -->
+    <dimen name="system_app_widget_inner_radius" android:featureFlag="android.appwidget.flags.use_smaller_app_widget_radius">16dp</dimen>
     <!-- System-provided padding for inner views on app widgets. The resolved value of this resource may change at runtime. @removed -->
     <dimen name="__removed_system_app_widget_internal_padding">16dp</dimen>
 
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 581dee5..bb5380e 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -34,7 +34,7 @@
          http://smscoin.net/software/engine/WordPress/Paid+SMS-registration/ -->
 
     <!-- Arab Emirates -->
-    <shortcode country="ae" pattern="\\d{1,5}" free="1017|1355|3214|6253" />
+    <shortcode country="ae" pattern="\\d{1,5}" free="1017|1355|3214|6253|6568" />
 
     <!-- Albania: 5 digits, known short codes listed -->
     <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" />
@@ -70,7 +70,7 @@
     <shortcode country="bh" pattern="\\d{1,5}" free="81181|85999" />
 
     <!-- Brazil: 1-5 digits (standard system default, not country specific) -->
-    <shortcode country="br" pattern="\\d{1,5}" free="6000[012]\\d|876|5500|9963|4141|8000|2652" />
+    <shortcode country="br" pattern="\\d{1,5}" free="6000[012]\\d|876|5500|9963|4141|8000|2652|26808" />
 
     <!-- Botswana: 1-5 digits (standard system default, not country specific) -->
     <shortcode country="bw" pattern="\\d{1,5}" free="16641" />
@@ -79,7 +79,7 @@
     <shortcode country="by" pattern="\\d{4}" premium="3336|4161|444[4689]|501[34]|7781" />
 
     <!-- Canada: 5-6 digits -->
-    <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188|43030" standard="244444" free="455677" />
+    <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188|43030" standard="244444" free="455677|24470" />
 
     <!-- Switzerland: 3-5 digits: http://www.swisscom.ch/fxres/kmu/thirdpartybusiness_code_of_conduct_en.pdf -->
     <shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111|30118" free="98765|30075|30047" />
@@ -123,8 +123,8 @@
          http://www.tja.ee/public/documents/Elektrooniline_side/Oigusaktid/ENG/Estonian_Numbering_Plan_annex_06_09_2010.mht -->
     <shortcode country="ee" pattern="1\\d{2,4}" premium="90\\d{5}|15330|1701[0-3]" free="116\\d{3}|95034" />
 
-    <!-- Egypt: 4 digits, known codes listed -->
-    <shortcode country="eg" pattern="\\d{4}" free="1499" />
+    <!-- Egypt: 4-5 digits, known codes listed -->
+    <shortcode country="eg" pattern="\\d{4,5}" free="1499|10020" />
 
     <!-- Spain: 5-6 digits: 25xxx, 27xxx, 280xx, 35xxx, 37xxx, 795xxx, 797xxx, 995xxx, 997xxx, plus EU.
          http://www.legallink.es/?q=en/content/which-current-regulatory-status-premium-rate-services-spain -->
@@ -147,7 +147,7 @@
     <shortcode country="ge" pattern="\\d{1,5}" premium="801[234]|888[239]" free="95201|95202|95203" />
 
     <!-- Ghana: 4 digits, known premium codes listed -->
-    <shortcode country="gh" pattern="\\d{4}" free="5041|3777|2333" />
+    <shortcode country="gh" pattern="\\d{4}" free="5041|3777|2333|6061" />
 
     <!-- Greece: 5 digits (54xxx, 19yxx, x=0-9, y=0-5): http://www.cmtelecom.com/premium-sms/greece -->
     <shortcode country="gr" pattern="\\d{5}" premium="54\\d{3}|19[0-5]\\d{2}" free="116\\d{3}|12115" />
@@ -169,7 +169,7 @@
     <shortcode country="in" pattern="\\d{1,5}" free="59336|53969" />
 
     <!-- Indonesia: 1-5 digits (standard system default, not country specific) -->
-    <shortcode country="id" pattern="\\d{1,5}" free="99477|6006|46645|363|93457|99265" />
+    <shortcode country="id" pattern="\\d{1,5}" free="99477|6006|46645|363|93457|99265|77413" />
 
     <!-- Ireland: 5 digits, 5xxxx (50xxx=free, 5[12]xxx=standard), plus EU:
          http://www.comreg.ie/_fileupload/publications/ComReg1117.pdf -->
@@ -226,13 +226,13 @@
     <shortcode country="mn" pattern="\\d{1,6}" free="44444|45678|445566" />
 
     <!-- Malawi: 1-5 digits (standard system default, not country specific) -->
-    <shortcode country="mw" pattern="\\d{1,5}" free="4276" />
+    <shortcode country="mw" pattern="\\d{1,5}" free="4276|4305" />
 
     <!-- Mozambique: 1-5 digits (standard system default, not country specific) -->
     <shortcode country="mz" pattern="\\d{1,5}" free="1714" />
 
     <!-- Mexico: 4-7 digits (not confirmed), known premium codes listed -->
-    <shortcode country="mx" pattern="\\d{4,7}" premium="53035|7766" free="26259|46645|50025|50052|5050|76551|88778|9963|91101|45453|550346|3030303|81811" />
+    <shortcode country="mx" pattern="\\d{4,7}" premium="53035|7766" free="26259|46645|50025|50052|5050|76551|88778|9963|91101|45453|550346|3030303|81811|81818" />
 
     <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf -->
     <shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288|66668|66966" />
@@ -324,7 +324,7 @@
     <shortcode country="tj" pattern="\\d{4}" premium="11[3-7]1|4161|4333|444[689]" />
 
     <!-- Tanzania: 1-5 digits (standard system default, not country specific) -->
-    <shortcode country="tz" pattern="\\d{1,5}" free="15046|15234|15324" />
+    <shortcode country="tz" pattern="\\d{1,5}" free="15046|15234|15324|15610" />
 
     <!-- Tunisia: 5 digits, known premium codes listed -->
     <shortcode country="tn" pattern="\\d{5}" free="85799" />
@@ -336,11 +336,11 @@
     <shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" />
 
     <!-- Uganda(UG): 4 digits (standard system default, not country specific) -->
-    <shortcode country="ug" pattern="\\d{4}" free="8000" />
+    <shortcode country="ug" pattern="\\d{4}" free="8000|8009" />
 
     <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm),
          visual voicemail code for T-Mobile: 122 -->
-    <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" standard="44567|244444" free="122|87902|21696|24614|28003|30356|33669|40196|41064|41270|43753|44034|46645|52413|56139|57969|61785|66975|75136|76227|81398|83952|85140|86566|86799|95737|96684|99245|611611|96831" />
+    <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" standard="44567|244444" free="122|87902|21696|24614|28003|30356|33669|40196|41064|41270|43753|44034|46645|52413|56139|57969|61785|66975|75136|76227|81398|83952|85140|86566|86799|95737|96684|99245|611611|96831|10907" />
 
     <!--Uruguay : 1-6 digits (standard system default, not country specific) -->
     <shortcode country="uy" pattern="\\d{1,6}" free="55002|191289" />
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index 46bd73e..4d6c30e 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -686,7 +686,7 @@
         return new BackMotionEvent(
                 /* touchX = */ 0,
                 /* touchY = */ 0,
-                /* frameTime = */ 0,
+                /* frameTimeMillis = */ 0,
                 /* progress = */ progress,
                 /* triggerBack = */ false,
                 /* swipeEdge = */ BackEvent.EDGE_LEFT,
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index a028e18..debd0df 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -659,5 +659,6 @@
    <privapp-permissions package="com.android.devicediagnostics">
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.BATTERY_STATS"/>
+        <permission name="android.permission.ENTER_TRADE_IN_MODE"/>
     </privapp-permissions>
 </permissions>
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index cb3b64c..93d94c9 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -16,6 +16,7 @@
 
 package android.graphics;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 
 import java.lang.annotation.Retention;
@@ -41,6 +42,7 @@
              Y8,
              Y16,
              YCBCR_P010,
+             YCBCR_P210,
              NV16,
              NV21,
              YUY2,
@@ -206,6 +208,26 @@
     public static final int YCBCR_P010 = 0x36;
 
     /**
+     * <p>Android YUV P210 format.</p>
+     *
+     * P210 is a 4:2:2 YCbCr semiplanar format comprised of a WxH Y plane
+     * followed by a WxH CbCr plane. Each sample is represented by a 16-bit
+     * little-endian value, with the lower 6 bits set to zero.
+     *
+     * <p>For example, the {@link android.media.Image} object can provide data
+     * in this format from a {@link android.hardware.camera2.CameraDevice}
+     * through a {@link android.media.ImageReader} object if this format is
+     * supported by {@link android.hardware.camera2.CameraDevice}.</p>
+     *
+     * @see android.media.Image
+     * @see android.media.ImageReader
+     * @see android.hardware.camera2.CameraDevice
+     *
+     */
+    @FlaggedApi(android.media.codec.Flags.FLAG_P210_FORMAT_SUPPORT)
+    public static final int YCBCR_P210 = 0x3c;
+
+    /**
      * YCbCr format, used for video.
      *
      * <p>For the {@link android.hardware.camera2} API, the {@link #YUV_420_888} format is
@@ -849,6 +871,8 @@
                 return 16;
             case YCBCR_P010:
                 return 24;
+            case YCBCR_P210:
+                return 32;
             case RAW_DEPTH10:
             case RAW10:
                 return 10;
@@ -899,7 +923,9 @@
             case JPEG_R:
                 return true;
         }
-
+        if (android.media.codec.Flags.p210FormatSupport() && format == YCBCR_P210) {
+            return true;
+        }
         return false;
     }
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
index a3d2d7f..4385327 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
@@ -16,6 +16,10 @@
 
 package androidx.window.extensions.area;
 
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
+import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
 import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
 
 import android.app.Activity;
@@ -23,6 +27,7 @@
 import android.hardware.devicestate.DeviceState;
 import android.hardware.devicestate.DeviceStateManager;
 import android.hardware.devicestate.DeviceStateRequest;
+import android.hardware.devicestate.feature.flags.Flags;
 import android.hardware.display.DisplayManager;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
@@ -72,18 +77,18 @@
     @GuardedBy("mLock")
     private final ArraySet<Consumer<ExtensionWindowAreaStatus>>
             mRearDisplayPresentationStatusListeners = new ArraySet<>();
-    private final int mRearDisplayState;
+    private int mRearDisplayState = INVALID_DEVICE_STATE_IDENTIFIER;
     private final int mConcurrentDisplayState;
     @NonNull
-    private final int[] mFoldedDeviceStates;
+    private int[] mFoldedDeviceStates = new int[0];
     private long mRearDisplayAddress = INVALID_DISPLAY_ADDRESS;
     @WindowAreaSessionState
     private int mRearDisplaySessionStatus = WindowAreaComponent.SESSION_STATE_INACTIVE;
 
     @GuardedBy("mLock")
-    private int mCurrentDeviceState = INVALID_DEVICE_STATE_IDENTIFIER;
+    private DeviceState mCurrentDeviceState = INVALID_DEVICE_STATE;
     @GuardedBy("mLock")
-    private int[] mCurrentSupportedDeviceStates;
+    private List<DeviceState> mCurrentSupportedDeviceStates;
 
     @GuardedBy("mLock")
     private DeviceStateRequest mRearDisplayStateRequest;
@@ -103,16 +108,25 @@
         mDisplayManager = context.getSystemService(DisplayManager.class);
         mExecutor = context.getMainExecutor();
 
-        // TODO(b/329436166): Update the usage of device state manager API's
-        mCurrentSupportedDeviceStates = getSupportedStateIdentifiers(
-                mDeviceStateManager.getSupportedDeviceStates());
-        mFoldedDeviceStates = context.getResources().getIntArray(
-                R.array.config_foldedDeviceStates);
+        mCurrentSupportedDeviceStates = mDeviceStateManager.getSupportedDeviceStates();
 
-        // TODO(b/236022708) Move rear display state to device state config file
-        mRearDisplayState = context.getResources().getInteger(
-                R.integer.config_deviceStateRearDisplay);
+        if (Flags.deviceStatePropertyMigration()) {
+            for (int i = 0; i < mCurrentSupportedDeviceStates.size(); i++) {
+                DeviceState state = mCurrentSupportedDeviceStates.get(i);
+                if (state.hasProperty(PROPERTY_FEATURE_REAR_DISPLAY)) {
+                    mRearDisplayState = state.getIdentifier();
+                    break;
+                }
+            }
+        } else {
+            mFoldedDeviceStates = context.getResources().getIntArray(
+                    R.array.config_foldedDeviceStates);
+            // TODO(b/236022708) Move rear display state to device state config file
+            mRearDisplayState = context.getResources().getInteger(
+                    R.integer.config_deviceStateRearDisplay);
+        }
 
+        // TODO(b/374351956) Use DeviceState API when the dual display state is always returned
         mConcurrentDisplayState = context.getResources().getInteger(
                 R.integer.config_deviceStateConcurrentRearDisplay);
 
@@ -147,7 +161,7 @@
             mRearDisplayStatusListeners.add(consumer);
 
             // If current device state is still invalid, the initial value has not been provided.
-            if (mCurrentDeviceState == INVALID_DEVICE_STATE_IDENTIFIER) {
+            if (mCurrentDeviceState.getIdentifier() == INVALID_DEVICE_STATE_IDENTIFIER) {
                 return;
             }
             consumer.accept(getCurrentRearDisplayModeStatus());
@@ -312,7 +326,7 @@
             mRearDisplayPresentationStatusListeners.add(consumer);
 
             // If current device state is still invalid, the initial value has not been provided
-            if (mCurrentDeviceState == INVALID_DEVICE_STATE_IDENTIFIER) {
+            if (mCurrentDeviceState.getIdentifier() == INVALID_DEVICE_STATE_IDENTIFIER) {
                 return;
             }
             @WindowAreaStatus int currentStatus = getCurrentRearDisplayPresentationModeStatus();
@@ -452,8 +466,7 @@
     @Override
     public void onSupportedStatesChanged(@NonNull List<DeviceState> supportedStates) {
         synchronized (mLock) {
-            // TODO(b/329436166): Update the usage of device state manager API's
-            mCurrentSupportedDeviceStates = getSupportedStateIdentifiers(supportedStates);
+            mCurrentSupportedDeviceStates = supportedStates;
             updateRearDisplayStatusListeners(getCurrentRearDisplayModeStatus());
             updateRearDisplayPresentationStatusListeners(
                     getCurrentRearDisplayPresentationModeStatus());
@@ -463,8 +476,7 @@
     @Override
     public void onDeviceStateChanged(@NonNull DeviceState state) {
         synchronized (mLock) {
-            // TODO(b/329436166): Update the usage of device state manager API's
-            mCurrentDeviceState = state.getIdentifier();
+            mCurrentDeviceState = state;
             updateRearDisplayStatusListeners(getCurrentRearDisplayModeStatus());
             updateRearDisplayPresentationStatusListeners(
                     getCurrentRearDisplayPresentationModeStatus());
@@ -477,7 +489,8 @@
             return WindowAreaComponent.STATUS_UNSUPPORTED;
         }
 
-        if (!ArrayUtils.contains(mCurrentSupportedDeviceStates, mRearDisplayState)) {
+        if (!deviceStateListContainsIdentifier(mCurrentSupportedDeviceStates,
+                mRearDisplayState)) {
             return WindowAreaComponent.STATUS_UNAVAILABLE;
         }
 
@@ -488,15 +501,6 @@
         return WindowAreaComponent.STATUS_AVAILABLE;
     }
 
-    // TODO(b/329436166): Remove and update the usage of device state manager API's
-    private int[] getSupportedStateIdentifiers(@NonNull List<DeviceState> states) {
-        int[] identifiers = new int[states.size()];
-        for (int i = 0; i < states.size(); i++) {
-            identifiers[i] = states.get(i).getIdentifier();
-        }
-        return identifiers;
-    }
-
     /**
      * Helper method to determine if a rear display session is currently active by checking
      * if the current device state is that which corresponds to {@code mRearDisplayState}.
@@ -505,7 +509,31 @@
      */
     @GuardedBy("mLock")
     private boolean isRearDisplayActive() {
-        return mCurrentDeviceState == mRearDisplayState;
+        if (Flags.deviceStatePropertyApi()) {
+            return mCurrentDeviceState.hasProperty(PROPERTY_FEATURE_REAR_DISPLAY);
+        } else {
+            return mCurrentDeviceState.getIdentifier() == mRearDisplayState;
+        }
+    }
+
+    @GuardedBy("mLock")
+    private boolean isRearDisplayPresentationModeActive() {
+        if (Flags.deviceStatePropertyApi()) {
+            return mCurrentDeviceState.hasProperty(PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT);
+        } else {
+            return mCurrentDeviceState.getIdentifier() == mConcurrentDisplayState;
+        }
+    }
+
+    @GuardedBy("mLock")
+    private boolean deviceStateListContainsIdentifier(List<DeviceState> deviceStates,
+            int identifier) {
+        for (int i = 0; i < deviceStates.size(); i++) {
+            if (deviceStates.get(i).getIdentifier() == identifier) {
+                return true;
+            }
+        }
+        return false;
     }
 
     @GuardedBy("mLock")
@@ -526,12 +554,12 @@
             return WindowAreaComponent.STATUS_UNSUPPORTED;
         }
 
-        if (mCurrentDeviceState == mConcurrentDisplayState) {
+        if (isRearDisplayPresentationModeActive()) {
             return WindowAreaComponent.STATUS_ACTIVE;
         }
 
-        if (!ArrayUtils.contains(mCurrentSupportedDeviceStates, mConcurrentDisplayState)
-                || isDeviceFolded()) {
+        if (!deviceStateListContainsIdentifier(mCurrentSupportedDeviceStates,
+                mConcurrentDisplayState) || isDeviceFolded()) {
             return WindowAreaComponent.STATUS_UNAVAILABLE;
         }
         return WindowAreaComponent.STATUS_AVAILABLE;
@@ -539,7 +567,12 @@
 
     @GuardedBy("mLock")
     private boolean isDeviceFolded() {
-        return ArrayUtils.contains(mFoldedDeviceStates, mCurrentDeviceState);
+        if (Flags.deviceStatePropertyApi()) {
+            return mCurrentDeviceState.hasProperty(
+                    PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY);
+        } else {
+            return ArrayUtils.contains(mFoldedDeviceStates, mCurrentDeviceState.getIdentifier());
+        }
     }
 
     @GuardedBy("mLock")
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index a0718d9..b29e8bf 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Gryp skerm vas"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App kan nie hierheen geskuif word nie"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimeer"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Stel terug"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Spring na links"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Spring na regs"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Maak By Verstek Oop-instellings"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index f160c70b..d96033f 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ማያ ገጹን አሳድግ"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"መተግበሪያ ወደዚህ መንቀሳቀስ አይችልም"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"አሳድግ"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ወደነበረበት መልስ"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ወደ ግራ አሳድግ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ወደ ቀኝ አሳድግ"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"በነባሪ ቅንብሮች ክፈት"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 81706a2..42ef4c3 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"التقاط صورة للشاشة"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"لا يمكن نقل التطبيق إلى هنا"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"تكبير"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"استعادة"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"المحاذاة إلى اليسار"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"المحاذاة إلى اليمين"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"إعدادات الفتح تلقائيًا"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 9fd4941..8e9c704 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -134,6 +134,8 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"স্ক্ৰীন স্নেপ কৰক"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ইয়ালৈ এপ্‌টো আনিব নোৱাৰি"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"মেক্সিমাইজ কৰক"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_restore_button_text (4234449220944704387) -->
+    <skip />
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"বাওঁফাললৈ স্নেপ কৰক"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"সোঁফাললৈ স্নেপ কৰক"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ডিফ’ল্ট ছেটিং খোলক"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 3ab6397..1310f6f 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranı çəkin"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Tətbiqi bura köçürmək mümkün deyil"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Böyüdün"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Bərpa edin"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Sola tərəf çəkin"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Sağa tərəf çəkin"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Defolt ayarlarla açın"</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 5076256..b9c4239 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Uklopi ekran"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija ne može da se premesti ovde"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Uvećajte"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Vratite"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Prikačite levo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Prikačite desno"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Podešavanje Podrazumevano otvaraj"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 95530c4..5d389d8 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Размясціць на палавіне экрана"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Нельга перамясціць сюды праграму"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Разгарнуць"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Аднавіць"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Размясціць злева"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Размясціць справа"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Налады параметра \"Адкрываць стандартна\""</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index db498c1..8078786 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Прилепване на екрана"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложението не може да бъде преместено тук"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Увеличаване"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Възстановяване"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Прилепване наляво"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Прилепване надясно"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Отваряне на настройките по подразбиране"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 4c20253..8db7144 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -134,6 +134,8 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"স্ক্রিনে অ্যাপ মানানসই হিসেবে ছোট বড় করুন"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"অ্যাপটি এখানে সরানো যাবে না"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"বড় করুন"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_restore_button_text (4234449220944704387) -->
+    <skip />
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"বাঁদিকে স্ন্যাপ করুন"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ডানদিকে স্ন্যাপ করুন"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ডিফল্ট হিসেবে থাকা সেটিংস খুলুন"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 102a912..3d922d8 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snimi ekran"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ne možete premjestiti aplikaciju ovdje"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimiziranje"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Vraćanje"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Pomicanje ulijevo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Pomicanje udesno"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Otvaranje prema zadanim postavkama"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 3e3fcd0..dc96cd0 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajusta la pantalla"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"L\'aplicació no es pot moure aquí"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximitza"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaura"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajusta a l\'esquerra"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ajusta a la dreta"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Configuració d\'obertura predeterminada"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index 0627f54..30ba78a 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Rozpůlit obrazovku"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikaci sem nelze přesunout"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximalizovat"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Obnovit"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Přichytit vlevo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Přichytit vpravo"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Otevírat podle výchozího nastavení"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index ed9e5f0..433b858 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Tilpas skærm"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apps kan ikke flyttes hertil"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimér"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Gendan"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Fastgør til venstre"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Fastgør til højre"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Indstillinger for automatisk åbning"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index ec1cb03..0b4d189 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -134,6 +134,8 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Bildschirm teilen"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Die App kann nicht hierher verschoben werden"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximieren"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_restore_button_text (4234449220944704387) -->
+    <skip />
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Links andocken"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Rechts andocken"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Einstellungen für die Option „Standardmäßig öffnen“"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 7a690ce..beff019 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Προβολή στο μισό της οθόνης"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Δεν είναι δυνατή η μετακίνηση της εφαρμογής εδώ"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Μεγιστοποίηση"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Επαναφορά"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Κούμπωμα αριστερά"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Κούμπωμα δεξιά"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Άνοιγμα ρυθμίσεων από προεπιλογή"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index afb3f8e..01d3d25 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximise"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restore"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Snap left"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Snap right"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Open by default settings"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index aa39251..20ec076 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap Screen"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximize"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restore"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Snap left"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Snap right"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Open by default settings"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index afb3f8e..01d3d25 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximise"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restore"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Snap left"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Snap right"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Open by default settings"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index afb3f8e..01d3d25 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximise"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restore"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Snap left"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Snap right"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Open by default settings"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 5244a61..c9e7ecb 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar pantalla"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"No se puede mover la app aquí"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restablecer"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajustar a la izquierda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ajustar a la derecha"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Abrir con la configuración predeterminada"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index a673351..903294b 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar pantalla"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"La aplicación no se puede mover aquí"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Acoplar a la izquierda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Acoplar a la derecha"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Abrir con los ajustes predeterminados"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 686385c..f6bebff 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Kuva poolel ekraanil"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Rakendust ei saa siia teisaldada"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimeeri"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Taasta"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Tõmmake vasakule"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Tõmmake paremale"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Avamisviisi vaikeseaded"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 1f0e54c..267452f 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Zatitu pantaila"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikazioa ezin da hona ekarri"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizatu"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Leheneratu"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ezarri ezkerrean"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ezarri eskuinean"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Modu lehenetsian irekitzearen ezarpenak"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index ad39b28..ec4779b 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"بزرگ کردن صفحه"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"برنامه را نمی‌توان به اینجا منتقل کرد"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"بزرگ کردن"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"بازیابی کردن"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"کشیدن به‌چپ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"کشیدن به‌راست"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"تنظیمات باز کردن به‌طور پیش‌فرض"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index 2f0edd3..6dcd20c 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Jaa näyttö"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Sovellusta ei voi siirtää tänne"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Suurenna"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Palauta"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Siirrä vasemmalle"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Siirrä oikealle"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Avaa oletusasetusten mukaan"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 2453961..df6d503 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Aligner l\'écran"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Agrandir"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurer"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Épingler à gauche"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Épingler à droite"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Ouvrir les paramètres par défaut"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index aee2345..3a7f2f0 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fractionner l\'écran"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Agrandir"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurer"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ancrer à gauche"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ancrer à droite"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Ouvrir les paramètres par défaut"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index b61588a..cb7bb32 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Encaixar pantalla"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Non se pode mover aquí a aplicación"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Axustar á esquerda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Axustar á dereita"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Abrir coa configuración predeterminada"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index fd4f2ba..bee06fe 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -134,6 +134,8 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"સ્ક્રીન સ્નૅપ કરો"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ઍપ અહીં ખસેડી શકાતી નથી"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"મોટું કરો"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_restore_button_text (4234449220944704387) -->
+    <skip />
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ડાબે સ્નૅપ કરો"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"જમણે સ્નૅપ કરો"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"\'ડિફૉલ્ટ તરીકે ખોલો\' સેટિંગ"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index d2cd23d..2c14199 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्नैप स्क्रीन"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ऐप्लिकेशन को यहां मूव नहीं किया जा सकता"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"बड़ा करें"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"पहले जैसा करें"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"बाईं ओर स्नैप करें"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"दाईं ओर स्नैप करें"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"डिफ़ॉल्ट सेटिंग के हिसाब से खोलें"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 80949b4..a2a52d1 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Izradi snimku zaslona"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija se ne može premjestiti ovdje"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimiziraj"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Vrati"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Poravnaj lijevo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Poravnaj desno"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Otvori prema zadanim postavkama"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index cebf585..03cc9f5 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Igazodás a képernyő adott részéhez"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Az alkalmazás nem helyezhető át ide"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Teljes méret"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Visszaállítás"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Balra igazítás"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Jobbra igazítás"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Alapértelmezett beállítások megnyitása"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 63a9d6d..28c762e 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ծալել էկրանը"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Հավելվածը հնարավոր չէ տեղափոխել այստեղ"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Ծավալել"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Վերականգնել"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ամրացնել ձախ կողմում"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ամրացնել աջ կողմում"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Բացել կարգավորումներն ըստ կանխադրման"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index a06d01c..4929b79 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Gabungkan Layar"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikasi tidak dapat dipindahkan ke sini"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimalkan"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Pulihkan"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Maksimalkan ke kiri"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Maksimalkan ke kanan"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Buka dengan setelan default"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index a20f460..d7ba53f 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Smelluskjár"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ekki er hægt að færa forritið hingað"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Stækka"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Endurheimta"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Smella til vinstri"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Smella til hægri"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Stillingar sjálfvirkrar opnunar"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 39fd6ba..4522d37 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Aggancia schermo"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossibile spostare l\'app qui"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Ingrandisci"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Ripristina"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Aggancia a sinistra"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Aggancia a destra"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Apri in base alle impostazioni predefinite"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 0586d1f..110d357 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"כיווץ המסך"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"לא ניתן להעביר את האפליקציה לכאן"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"הגדלה"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"שחזור"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"הצמדה לשמאל"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"הצמדה לימין"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"הגדרות לפתיחה כברירת מחדל"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 8aa8269..69421da 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"画面のスナップ"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"アプリはここに移動できません"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"最大化"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"復元"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"左にスナップ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"右にスナップ"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"デフォルトの設定で開く"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 6672599..4685988 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"აპლიკაციის დაპატარავება ეკრანზე"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"აპის აქ გადატანა შეუძლებელია"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"მაქსიმალურად გაშლა"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"აღდგენა"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"მარცხნივ გადატანა"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"მარჯვნივ გადატანა"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"პარამეტრების ნაგულისხმევად გახსნა"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 56ae441..84e7ea5 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Экранды бөлу"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Қолданба бұл жерге қойылмайды."</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Жаю"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Қалпына келтіру"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Солға тіркеу"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Оңға тіркеу"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Әдепкісінше ашу параметрлері"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 460b867..7eb81e1 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ថតអេក្រង់"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"មិនអាចផ្លាស់ទីកម្មវិធីមកទីនេះបានទេ"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ពង្រីក"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ស្ដារ"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ផ្លាស់ទីទៅឆ្វេង"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ផ្លាស់ទីទៅស្ដាំ"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ការកំណត់បើកតាមលំនាំដើម"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 2e2be46c..2b43f57 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ಸ್ನ್ಯಾಪ್ ಸ್ಕ್ರೀನ್"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ಆ್ಯಪ್ ಅನ್ನು ಇಲ್ಲಿಗೆ ಸರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ಮರುಸ್ಥಾಪಿಸಿ"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ಎಡಕ್ಕೆ ಸ್ನ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ಬಲಕ್ಕೆ ಸ್ನ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ಡೀಫಾಲ್ಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಂದ ತೆರೆಯಿರಿ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 4bcc76d..8f36aab 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"화면 분할"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"앱을 여기로 이동할 수 없음"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"최대화하기"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"복원"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"왼쪽으로 맞추기"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"오른쪽으로 맞추기"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"기본값으로 열기 설정"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 6ae51a4..c1219ba 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Экранды сүрөткө тартып алуу"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Колдонмону бул жерге жылдырууга болбойт"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Чоңойтуу"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Калыбына келтирүү"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Солго жылдыруу"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Оңго жылдыруу"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Демейки шартта ачуу параметрлери"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index f8a09da..375fc64 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -134,6 +134,8 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ສະແນັບໜ້າຈໍ"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ບໍ່ສາມາດຍ້າຍແອັບມາບ່ອນນີ້ໄດ້"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ຂະຫຍາຍໃຫຍ່ສຸດ"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_restore_button_text (4234449220944704387) -->
+    <skip />
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ແນບຊ້າຍ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ແນບຂວາ"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ເປີດຕາມການຕັ້ງຄ່າເລີ່ມຕົ້ນ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 857e90e..dfc3b45 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Sutraukti ekraną"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Programos negalima perkelti čia"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Padidinti"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Atkurti"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Pritraukti kairėje"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Pritraukti dešinėje"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Atidaryti pagal numatytuosius nustatymus"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index e56363e..8781852 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fiksēt ekrānu"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Lietotni nevar pārvietot šeit."</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimizēt"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Atjaunot"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Piestiprināt pa kreisi"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Piestiprināt pa labi"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Atvērt pēc noklusējuma iestatījumiem"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 1bf7a28..88fed74 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Подели го екранот на половина"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликацијата не може да се премести овде"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Максимизирај"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Врати"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Фотографирај лево"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Фотографирај десно"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Отвори според стандардните поставки"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 3401f6d..71fb78e 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"സ്‌ക്രീൻ സ്‌നാപ്പ് ചെയ്യുക"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ആപ്പ് ഇവിടേക്ക് നീക്കാനാകില്ല"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"വലുതാക്കുക"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"പുനഃസ്ഥാപിക്കുക"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ഇടതുവശത്തേക്ക് സ്‌നാപ്പ് ചെയ്യുക"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"വലതുവശത്തേക്ക് സ്‌നാപ്പ് ചെയ്യുക"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ഡിഫോൾട്ട് ക്രമീകരണം ഉപയോഗിച്ച് തുറക്കുക"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 87708d0..04f2f82 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -134,6 +134,8 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Дэлгэцийг таллах"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Аппыг ийш зөөх боломжгүй"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Томруулах"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_restore_button_text (4234449220944704387) -->
+    <skip />
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Зүүн тийш зэрэгцүүлэх"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Баруун тийш зэрэгцүүлэх"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Өгөгдмөл тохиргоогоор нээх"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index 1ea41e5..be1df32 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्क्रीन स्नॅप करा"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"अ‍ॅप इथे हलवू शकत नाही"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"मोठे करा"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"रिस्टोअर करा"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"डावीकडे स्नॅप करा"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"उजवीकडे स्नॅप करा"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"बाय डीफॉल्ट सेटिंग्ज उघडा"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index ca248e1..04da886 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Tangkap Skrin"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apl tidak boleh dialihkan ke sini"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimumkan"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Pulihkan"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Autojajar ke kiri"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Autojajar ke kanan"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Buka tetapan secara lalai"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 3c4325bf..915a7cd 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"စခရင်ကို ချုံ့မည်"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"အက်ပ်ကို ဤနေရာသို့ ရွှေ့၍မရပါ"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ချဲ့ရန်"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ပြန်ပြောင်းရန်"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ဘယ်တွင် ချဲ့ရန်"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ညာတွင် ချဲ့ရန်"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"မူရင်းဆက်တင်ဖြင့် ဖွင့်ရန်"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 4096bbf..8e5aee1 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fest skjermen"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Appen kan ikke flyttes hit"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimer"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Gjenopprett"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Fest til venstre"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Fest til høyre"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Innstillinger for åpning som standard"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 2fc5e09..42f2336 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्क्रिन स्न्याप गर्नुहोस्"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"एप सारेर यहाँ ल्याउन सकिएन"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ठुलो बनाउनुहोस्"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"रिस्टोर गर्नुहोस्"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"बायाँतिर स्न्याप गर्नुहोस्"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"दायाँतिर स्न्याप गर्नुहोस्"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"डिफल्ट सेटिङअनुसार खोल्नुहोस्"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 65fd8ea..d19a4d4 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Scherm halveren"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Kan de app niet hierheen verplaatsen"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximaliseren"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Herstellen"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Links uitlijnen"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Rechts uitlijnen"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Instellingen voor Standaard openen"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index 1f96daa..f67a6b2 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -134,6 +134,8 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ସ୍କ୍ରିନକୁ ସ୍ନାପ କରନ୍ତୁ"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ଆପକୁ ଏଠାକୁ ମୁଭ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ବଡ଼ କରନ୍ତୁ"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_restore_button_text (4234449220944704387) -->
+    <skip />
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ବାମରେ ସ୍ନାପ କରନ୍ତୁ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ଡାହାଣରେ ସ୍ନାପ କରନ୍ତୁ"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ଡିଫଲ୍ଟ ସେଟିଂସକୁ ଖୋଲନ୍ତୁ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index f93f509..76d59af 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -134,6 +134,8 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ਸਕ੍ਰੀਨ ਨੂੰ ਸਨੈਪ ਕਰੋ"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ਐਪ ਨੂੰ ਇੱਥੇ ਨਹੀਂ ਲਿਜਾਇਆ ਜਾ ਸਕਦਾ"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ਵੱਡਾ ਕਰੋ"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_restore_button_text (4234449220944704387) -->
+    <skip />
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ਖੱਬੇ ਪਾਸੇ ਸਨੈਪ ਕਰੋ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ਸੱਜੇ ਪਾਸੇ ਸਨੈਪ ਕਰੋ"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਸੈਟਿੰਗਾਂ ਮੁਤਾਬਕ ਖੋਲ੍ਹੋ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 1e76e82..502e53ab 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Przyciągnij ekran"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Nie można przenieść aplikacji tutaj"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksymalizuj"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Przywróć"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Przyciągnij do lewej"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Przyciągnij do prawej"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Ustawienia domyślnego otwierania"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 0bdb078..3ec5e76 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar tela"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover o app para cá"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajustar à esquerda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ajustar à direita"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Configurações \"Abrir por padrão\""</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 0e10da1..184a5b3 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Encaixar ecrã"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover a app para aqui"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Encaixar à esquerda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Encaixar à direita"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Definições de Abrir por predefinição"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 0bdb078..3ec5e76 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar tela"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover o app para cá"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajustar à esquerda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ajustar à direita"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Configurações \"Abrir por padrão\""</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index c942736..9703328 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Micșorează fereastra și fixeaz-o"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplicația nu poate fi mutată aici"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizează"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restabilește"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Trage la stânga"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Trage la dreapta"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Setări de deschidere în mod prestabilit"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index e2c3938..401a8aab 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Свернуть"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложение нельзя сюда переместить"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Развернуть"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Восстановить"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Привязать слева"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Привязать справа"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Настройки, регулирующие, как по умолчанию открываются ссылки"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 83a09f5..c101b4c 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -134,6 +134,8 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ස්නැප් තිරය"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"යෙදුම මෙතැනට ගෙන යා නොහැක"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"විහිදන්න"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_restore_button_text (4234449220944704387) -->
+    <skip />
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"වමට ස්නැප් කරන්න"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"දකුණට ස්නැප් කරන්න"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"පෙරනිමි සැකසීම් මඟින් විවෘත කරන්න"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index 1b3907e..7214300 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Zobraziť polovicu obrazovky"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikácia sa sem nedá presunúť"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximalizovať"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Obnoviť"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Prichytiť vľavo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Prichytiť vpravo"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Otvárať podľa predvolených nastavení"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 0a1b4a6..04fe7e89 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Pripni zaslon"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacije ni mogoče premakniti sem"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimiraj"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Obnovi"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Pripni levo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Pripni desno"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Nastavitve privzetega odpiranja"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 75120d2..6662ca1a 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -134,6 +134,8 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Regjistro ekranin"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacioni nuk mund të zhvendoset këtu"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimizo"</string>
+    <!-- no translation found for desktop_mode_maximize_menu_restore_button_text (4234449220944704387) -->
+    <skip />
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Zhvendos majtas"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Zhvendos djathtas"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Hap sipas cilësimeve të parazgjedhura"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 8b5c4df..d0a4ae6 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Уклопи екран"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликација не може да се премести овде"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Увећајте"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Вратите"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Прикачите лево"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Прикачите десно"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Подешавање Подразумевано отварај"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index e40b649..6ce2a9a 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fäst skärmen"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Det går inte att flytta appen hit"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Utöka"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Återställ"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Fäst till vänster"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Fäst till höger"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Inställningar för Öppna som standard"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index e63229c..40967f0 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Panga Madirisha kwenye Skrini"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Imeshindwa kuhamishia programu hapa"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Panua"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Rejesha"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Telezesha kushoto"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Telezesha kulia"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Fungua kwa mipangilio chaguomsingi"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 95972f1..3140c2c 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"திரையை ஸ்னாப் செய்"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ஆப்ஸை இங்கே நகர்த்த முடியாது"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"பெரிதாக்கும்"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"மீட்டெடுக்கும்"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"இடதுபுறம் நகர்த்தும்"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"வலதுபுறம் நகர்த்தும்"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"இயல்பாக அமைப்புகளைத் திறக்கும்"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 6223c83..62e62c7 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"స్క్రీన్‌ను స్నాప్ చేయండి"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"యాప్‌ను ఇక్కడకి తరలించడం సాధ్యం కాదు"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"మ్యాగ్జిమైజ్ చేయండి"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"రీస్టోర్ చేయండి"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ఎడమ వైపున స్నాప్ చేయండి"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"కుడి వైపున స్నాప్ చేయండి"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ఆటోమేటిక్ సెట్టింగ్‌ల ద్వారా తెరవండి"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index f74499c..e6386a2 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"สแนปหน้าจอ"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ย้ายแอปมาที่นี่ไม่ได้"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ขยายใหญ่สุด"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"คืนค่า"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"จัดพอดีกับทางซ้าย"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"จัดพอดีกับทางขวา"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"เปิดตามการตั้งค่าเริ่มต้น"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 7d984e0..176be33 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"I-snap ang Screen"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Hindi mailipat dito ang app"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"I-maximize"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"I-restore"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"I-snap pakaliwa"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"I-snap pakanan"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Buksan sa pamamagitan ng mga default na setting"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index ba186aa..73248e3 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranın Yarısına Tuttur"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Uygulama buraya taşınamıyor"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Ekranı kapla"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Geri yükle"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Sola tuttur"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Sağa tuttur"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Varsayılan olarak açma ayarları"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index 756e64d..a655a3eb 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Зафіксувати екран"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Сюди не можна перемістити додаток"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Розгорнути"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Відновити"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Закріпити ліворуч"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Закріпити праворуч"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Налаштування \"Відкривати за умовчанням\""</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 8aaa306..4bdea83 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"اسکرین کا اسناپ شاٹ لیں"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ایپ کو یہاں منتقل نہیں کیا جا سکتا"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"بڑا کریں"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"بحال کریں"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"دائیں منتقل کریں"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"بائیں منتقل کریں"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"بطور ڈیفالٹ ترتیبات کھولیں"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 4e4a58b..b3a496f 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranni biriktirish"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ilova bu yerga surilmaydi"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Yoyish"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Tiklash"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Chapga tortish"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Oʻngga tortish"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Birlamchi sozlamalar asosida ochish"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 09a143a..36d66e4 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Điều chỉnh kích thước màn hình"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Không di chuyển được ứng dụng đến đây"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Phóng to tối đa"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Khôi phục"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Di chuyển nhanh sang trái"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Di chuyển nhanh sang phải"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Mở các chế độ cài đặt theo mặc định"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 795febb..64446cd 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"屏幕快照"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"无法将应用移至此处"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"最大化"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"恢复"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"贴靠左侧"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"贴靠右侧"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"默认打开设置"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 0c6ad61..4970e8b 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"貼齊畫面"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至這裡"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"最大化"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"還原"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"貼齊左邊"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"貼齊右邊"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"採用預設設定打開"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 442a6fe..fcdccca 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"貼齊畫面"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至此處"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"最大化"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"還原"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"靠左對齊"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"靠右對齊"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"開啟連結的預設設定"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 47613d4..cbc6c02 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -134,6 +134,7 @@
     <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Thwebula Isikrini"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"I-app ayikwazi ukuhanjiswa lapha"</string>
     <string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Khulisa"</string>
+    <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Buyisela"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Chofoza kwesobunxele"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Chofoza kwesokudla"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Vula amasethingi ngokuzenzakalela"</string>
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/ManageWindowsViewContainer.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/ManageWindowsViewContainer.kt
index 79becb0..0e8e904 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/ManageWindowsViewContainer.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/ManageWindowsViewContainer.kt
@@ -122,7 +122,8 @@
                     snapshot.hardwareBuffer,
                     snapshot.colorSpace
                 )
-                val scaledSnapshotBitmap = snapshotBitmap?.let {
+                val croppedBitmap = snapshotBitmap?.let { cropBitmap(it) }
+                val scaledSnapshotBitmap = croppedBitmap?.let {
                     Bitmap.createScaledBitmap(
                         it, instanceIconWidth.toInt(), instanceIconHeight.toInt(), true /* filter */
                     )
@@ -160,6 +161,35 @@
             menuHeight += iconMargin.toInt()
         }
 
+        private fun cropBitmap(
+            bitmapToCrop: Bitmap
+        ): Bitmap {
+            val ratioToMatch = ICON_WIDTH_DP / ICON_HEIGHT_DP
+            val bitmapWidth = bitmapToCrop.width
+            val bitmapHeight = bitmapToCrop.height
+            if (bitmapWidth > bitmapHeight * ratioToMatch) {
+                // Crop based on height
+                val newWidth = bitmapHeight * ratioToMatch
+                return Bitmap.createBitmap(
+                    bitmapToCrop,
+                    ((bitmapWidth - newWidth) / 2).toInt(),
+                    0,
+                    newWidth.toInt(),
+                    bitmapHeight
+                )
+            } else {
+                // Crop based on width
+                val newHeight = bitmapWidth / ratioToMatch
+                return Bitmap.createBitmap(
+                    bitmapToCrop,
+                    0,
+                    ((bitmapHeight - newHeight) / 2).toInt(),
+                    bitmapWidth,
+                    newHeight.toInt()
+                )
+            }
+        }
+
         companion object {
             private const val MENU_RADIUS_DP = 26f
             private const val ICON_WIDTH_DP = 204f
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
index 7a56979..dc50fdb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
@@ -16,12 +16,15 @@
 
 package com.android.wm.shell.back;
 
+import static android.view.MotionEvent.ACTION_MOVE;
 import static android.view.RemoteAnimationTarget.MODE_CLOSING;
 import static android.view.RemoteAnimationTarget.MODE_OPENING;
 import static android.window.BackEvent.EDGE_RIGHT;
 
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_PREDICTIVE_BACK_CROSS_TASK;
+import static com.android.window.flags.Flags.predictiveBackTimestampApi;
 import static com.android.wm.shell.back.BackAnimationConstants.UPDATE_SYSUI_FLAGS_THRESHOLD;
+import static com.android.wm.shell.back.CrossActivityBackAnimationKt.scaleCentered;
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;
 
 import android.animation.Animator;
@@ -36,11 +39,14 @@
 import android.graphics.RectF;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.util.TimeUtils;
 import android.view.Choreographer;
 import android.view.IRemoteAnimationFinishedCallback;
 import android.view.IRemoteAnimationRunner;
+import android.view.MotionEvent;
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
+import android.view.VelocityTracker;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 import android.window.BackEvent;
@@ -48,6 +54,9 @@
 import android.window.BackProgressAnimator;
 import android.window.IOnBackInvokedCallback;
 
+import com.android.internal.dynamicanimation.animation.FloatValueHolder;
+import com.android.internal.dynamicanimation.animation.SpringAnimation;
+import com.android.internal.dynamicanimation.animation.SpringForce;
 import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.internal.policy.SystemBarUtils;
 import com.android.internal.protolog.ProtoLog;
@@ -81,6 +90,11 @@
     /** Duration of post animation after gesture committed. */
     private static final int POST_ANIMATION_DURATION_MS = 500;
 
+    private static final float SPRING_SCALE = 100f;
+    private static final float DEFAULT_FLING_VELOCITY = 320f;
+    private static final float MAX_FLING_VELOCITY = 1000f;
+    private static final float FLING_SPRING_STIFFNESS = 320f;
+
     private final Rect mStartTaskRect = new Rect();
     private float mCornerRadius;
     private int mStatusbarHeight;
@@ -114,6 +128,14 @@
     private float mInterWindowMargin;
     private float mVerticalMargin;
 
+    private final FloatValueHolder mPostCommitFlingScale = new FloatValueHolder(SPRING_SCALE);
+    private final SpringForce mPostCommitFlingSpring = new SpringForce(SPRING_SCALE)
+            .setStiffness(FLING_SPRING_STIFFNESS)
+            .setDampingRatio(1f);
+    private final VelocityTracker mVelocityTracker = VelocityTracker.obtain();
+    private float mGestureProgress = 0f;
+    private long mDownTime = 0L;
+
     @Inject
     public CrossTaskBackAnimation(Context context, BackAnimationBackground background,
             @ShellMainThread Handler handler) {
@@ -168,6 +190,7 @@
         if (mEnteringTarget == null || mClosingTarget == null) {
             return;
         }
+        mGestureProgress = progress;
 
         float touchY = event.getTouchY();
 
@@ -229,6 +252,8 @@
         }
 
         mClosingCurrentRect.set(left, top, left + width, top + height);
+
+        applyFlingScale(mClosingCurrentRect);
         applyTransform(mClosingTarget.leash, mClosingCurrentRect, mCornerRadius);
     }
 
@@ -239,9 +264,19 @@
         float height = mapRange(progress, mEnteringStartRect.height(), mStartTaskRect.height());
 
         mEnteringCurrentRect.set(left, top, left + width, top + height);
+
+        applyFlingScale(mEnteringCurrentRect);
         applyTransform(mEnteringTarget.leash, mEnteringCurrentRect, mCornerRadius);
     }
 
+    private void applyFlingScale(RectF rect) {
+        // apply a scale to the rect to account for fling velocity
+        final float flingScale = Math.min(mPostCommitFlingScale.getValue() / SPRING_SCALE, 1f);
+        if (flingScale >= 1f) return;
+        scaleCentered(rect, flingScale, /* pivotX */ rect.right,
+                /* pivotY */ rect.top + rect.height() / 2);
+    }
+
     /** Transform the target window to match the target rect. */
     private void applyTransform(SurfaceControl leash, RectF targetRect, float cornerRadius) {
         if (leash == null || !leash.isValid()) {
@@ -280,6 +315,9 @@
         mTransformMatrix.reset();
         mClosingCurrentRect.setEmpty();
         mInitialTouchPos.set(0, 0);
+        mGestureProgress = 0;
+        mDownTime = 0;
+        mVelocityTracker.clear();
 
         if (mFinishCallback != null) {
             try {
@@ -295,10 +333,24 @@
     private void onGestureProgress(@NonNull BackEvent backEvent) {
         if (!mBackInProgress) {
             mBackInProgress = true;
+            mDownTime = backEvent.getFrameTimeMillis();
         }
         float progress = backEvent.getProgress();
         mTouchPos.set(backEvent.getTouchX(), backEvent.getTouchY());
-        updateGestureBackProgress(getInterpolatedProgress(progress), backEvent);
+        float interpolatedProgress = getInterpolatedProgress(progress);
+        if (predictiveBackTimestampApi()) {
+            mVelocityTracker.addMovement(
+                    MotionEvent.obtain(
+                            /* downTime */ mDownTime,
+                            /* eventTime */ backEvent.getFrameTimeMillis(),
+                            /* action */ ACTION_MOVE,
+                            /* x */ interpolatedProgress * SPRING_SCALE,
+                            /* y */ 0f,
+                            /* metaState */ 0
+                    )
+            );
+        }
+        updateGestureBackProgress(interpolatedProgress, backEvent);
     }
 
     private void onGestureCommitted() {
@@ -307,6 +359,25 @@
             return;
         }
 
+        if (predictiveBackTimestampApi()) {
+            // kick off spring animation with the current velocity from the pre-commit phase, this
+            // affects the scaling of the closing and/or opening task during post-commit
+            mVelocityTracker.computeCurrentVelocity(1000);
+            float startVelocity = mGestureProgress < 0.1f
+                    ? -DEFAULT_FLING_VELOCITY : -mVelocityTracker.getXVelocity();
+            SpringAnimation flingAnimation =
+                    new SpringAnimation(mPostCommitFlingScale, SPRING_SCALE)
+                    .setStartVelocity(Math.max(-MAX_FLING_VELOCITY, Math.min(0f, startVelocity)))
+                    .setStartValue(SPRING_SCALE)
+                    .setMinimumVisibleChange(0.1f)
+                    .setSpring(mPostCommitFlingSpring);
+            flingAnimation.start();
+            // do an animation-frame immediately to prevent idle frame
+            flingAnimation.doAnimationFrame(
+                    Choreographer.getInstance().getLastFrameTimeNanos() / TimeUtils.NANOS_PER_MS
+            );
+        }
+
         // We enter phase 2 of the animation, the starting coordinates for phase 2 are the current
         // coordinate of the gesture driven phase.
         mEnteringCurrentRect.round(mEnteringStartRect);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIStatusManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIStatusManager.java
index 915a8a1..37369d1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIStatusManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIStatusManager.java
@@ -24,6 +24,7 @@
 /** Handle the visibility state of the Compat UI components. */
 public class CompatUIStatusManager {
 
+    private static final int COMPAT_UI_EDUCATION_UNDEFINED = -1;
     public static final int COMPAT_UI_EDUCATION_HIDDEN = 0;
     public static final int COMPAT_UI_EDUCATION_VISIBLE = 1;
 
@@ -32,24 +33,40 @@
     @NonNull
     private final IntSupplier mReader;
 
+    private int mCurrentValue = COMPAT_UI_EDUCATION_UNDEFINED;
+
     public CompatUIStatusManager(@NonNull IntConsumer writer, @NonNull IntSupplier reader) {
         mWriter = writer;
         mReader = reader;
     }
 
     public CompatUIStatusManager() {
-        this(i -> { }, () -> COMPAT_UI_EDUCATION_HIDDEN);
+        this(i -> {
+        }, () -> COMPAT_UI_EDUCATION_HIDDEN);
     }
 
     void onEducationShown() {
-        mWriter.accept(COMPAT_UI_EDUCATION_VISIBLE);
+        if (mCurrentValue != COMPAT_UI_EDUCATION_VISIBLE) {
+            mCurrentValue = COMPAT_UI_EDUCATION_VISIBLE;
+            mWriter.accept(mCurrentValue);
+        }
     }
 
     void onEducationHidden() {
-        mWriter.accept(COMPAT_UI_EDUCATION_HIDDEN);
+        if (mCurrentValue != COMPAT_UI_EDUCATION_HIDDEN) {
+            mCurrentValue = COMPAT_UI_EDUCATION_HIDDEN;
+            mWriter.accept(mCurrentValue);
+        }
     }
 
     boolean isEducationVisible() {
-        return mReader.getAsInt() == COMPAT_UI_EDUCATION_VISIBLE;
+        return getCurrentValue() == COMPAT_UI_EDUCATION_VISIBLE;
     }
-}
+
+    private int getCurrentValue() {
+        if (mCurrentValue == COMPAT_UI_EDUCATION_UNDEFINED) {
+            mCurrentValue = mReader.getAsInt();
+        }
+        return mCurrentValue;
+    }
+}
\ No newline at end of file
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 4c25889..b700a54 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
@@ -67,7 +67,7 @@
 import com.android.wm.shell.desktopmode.CloseDesktopTaskTransitionHandler;
 import com.android.wm.shell.desktopmode.DefaultDragToDesktopTransitionHandler;
 import com.android.wm.shell.desktopmode.DesktopActivityOrientationChangeHandler;
-import com.android.wm.shell.desktopmode.DesktopFullImmersiveTransitionHandler;
+import com.android.wm.shell.desktopmode.DesktopImmersiveController;
 import com.android.wm.shell.desktopmode.DesktopMixedTransitionHandler;
 import com.android.wm.shell.desktopmode.DesktopModeDragAndDropTransitionHandler;
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
@@ -397,12 +397,12 @@
             Context context,
             ShellInit shellInit,
             Transitions transitions,
-            Optional<DesktopFullImmersiveTransitionHandler> desktopImmersiveTransitionHandler,
+            Optional<DesktopImmersiveController> desktopImmersiveController,
             WindowDecorViewModel windowDecorViewModel,
             Optional<TaskChangeListener> taskChangeListener,
             FocusTransitionObserver focusTransitionObserver) {
         return new FreeformTaskTransitionObserver(
-                context, shellInit, transitions, desktopImmersiveTransitionHandler,
+                context, shellInit, transitions, desktopImmersiveController,
                 windowDecorViewModel, taskChangeListener, focusTransitionObserver);
     }
 
@@ -638,7 +638,7 @@
             ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
             DragToDesktopTransitionHandler dragToDesktopTransitionHandler,
             @DynamicOverride DesktopRepository desktopRepository,
-            Optional<DesktopFullImmersiveTransitionHandler> desktopFullImmersiveTransitionHandler,
+            Optional<DesktopImmersiveController> desktopImmersiveController,
             DesktopModeLoggerTransitionObserver desktopModeLoggerTransitionObserver,
             LaunchAdjacentController launchAdjacentController,
             RecentsTransitionHandler recentsTransitionHandler,
@@ -657,7 +657,7 @@
                 returnToDragStartAnimator, enterDesktopTransitionHandler,
                 exitDesktopTransitionHandler, desktopModeDragAndDropTransitionHandler,
                 toggleResizeDesktopTaskTransitionHandler,
-                dragToDesktopTransitionHandler, desktopFullImmersiveTransitionHandler.get(),
+                dragToDesktopTransitionHandler, desktopImmersiveController.get(),
                 desktopRepository,
                 desktopModeLoggerTransitionObserver, launchAdjacentController,
                 recentsTransitionHandler, multiInstanceHelper, mainExecutor, desktopTasksLimiter,
@@ -705,7 +705,7 @@
 
     @WMSingleton
     @Provides
-    static Optional<DesktopFullImmersiveTransitionHandler> provideDesktopImmersiveHandler(
+    static Optional<DesktopImmersiveController> provideDesktopImmersiveController(
             Context context,
             Transitions transitions,
             @DynamicOverride DesktopRepository desktopRepository,
@@ -713,7 +713,7 @@
             ShellTaskOrganizer shellTaskOrganizer) {
         if (DesktopModeStatus.canEnterDesktopMode(context)) {
             return Optional.of(
-                    new DesktopFullImmersiveTransitionHandler(
+                    new DesktopImmersiveController(
                             transitions,
                             desktopRepository,
                             displayController,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
similarity index 80%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandler.kt
rename to libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
index 9d4926b..d0bc5f0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
@@ -36,20 +36,21 @@
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
 import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.transition.Transitions.TransitionHandler
+import com.android.wm.shell.transition.Transitions.TransitionObserver
 import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
 
 /**
- * A [TransitionHandler] to move a task in/out of desktop's full immersive state where the task
+ * A controller to move tasks in/out of desktop's full immersive state where the task
  * remains freeform while being able to take fullscreen bounds and have its App Header visibility
  * be transient below the status bar like in fullscreen immersive mode.
  */
-class DesktopFullImmersiveTransitionHandler(
+class DesktopImmersiveController(
     private val transitions: Transitions,
     private val desktopRepository: DesktopRepository,
     private val displayController: DisplayController,
     private val shellTaskOrganizer: ShellTaskOrganizer,
     private val transactionSupplier: () -> SurfaceControl.Transaction,
-) : TransitionHandler {
+) : TransitionHandler, TransitionObserver {
 
     constructor(
         transitions: Transitions,
@@ -67,7 +68,7 @@
     private var state: TransitionState? = null
 
     @VisibleForTesting
-    val pendingExternalExitTransitions = mutableSetOf<ExternalPendingExit>()
+    val pendingExternalExitTransitions = mutableListOf<ExternalPendingExit>()
 
     /** Whether there is an immersive transition that hasn't completed yet. */
     private val inProgress: Boolean
@@ -137,14 +138,19 @@
      *
      * @param wct that will apply these changes
      * @param displayId of the display that should exit immersive mode
+     * @param excludeTaskId of the task to ignore (not exit) if it is the immersive one
      * @return a function to apply once the transition that will apply these changes is started
      */
     fun exitImmersiveIfApplicable(
         wct: WindowContainerTransaction,
-        displayId: Int
+        displayId: Int,
+        excludeTaskId: Int? = null,
     ): ((IBinder) -> Unit)? {
         if (!Flags.enableFullyImmersiveInDesktop()) return null
         val immersiveTask = desktopRepository.getTaskInFullImmersiveState(displayId) ?: return null
+        if (immersiveTask == excludeTaskId) {
+            return null
+        }
         val taskInfo = shellTaskOrganizer.getRunningTaskInfo(immersiveTask) ?: return null
         logV("Appending immersive exit for task: $immersiveTask in display: $displayId")
         wct.setBounds(taskInfo.token, getExitDestinationBounds(taskInfo))
@@ -179,6 +185,17 @@
         return null
     }
 
+
+    /** Whether the [change] in the [transition] is a known immersive change. */
+    fun isImmersiveChange(
+        transition: IBinder,
+        change: TransitionInfo.Change,
+    ): Boolean {
+        return pendingExternalExitTransitions.any {
+            it.transition == transition && it.taskId == change.taskInfo?.taskId
+        }
+    }
+
     private fun addPendingImmersiveExit(taskId: Int, displayId: Int, transition: IBinder) {
         pendingExternalExitTransitions.add(
             ExternalPendingExit(
@@ -196,10 +213,11 @@
         finishTransaction: SurfaceControl.Transaction,
         finishCallback: Transitions.TransitionFinishCallback
     ): Boolean {
+        logD("startAnimation transition=%s", transition)
         val state = requireState()
         if (transition != state.transition) return false
         animateResize(
-            transitionState = state,
+            targetTaskId = state.taskId,
             info = info,
             startTransaction = startTransaction,
             finishTransaction = finishTransaction,
@@ -209,40 +227,55 @@
     }
 
     private fun animateResize(
-        transitionState: TransitionState,
+        targetTaskId: Int,
         info: TransitionInfo,
         startTransaction: SurfaceControl.Transaction,
         finishTransaction: SurfaceControl.Transaction,
         finishCallback: Transitions.TransitionFinishCallback
     ) {
+        logD("animateResize for task#%d", targetTaskId)
         val change = info.changes.first { c ->
             val taskInfo = c.taskInfo
-            return@first taskInfo != null && taskInfo.taskId == transitionState.taskId
+            return@first taskInfo != null && taskInfo.taskId == targetTaskId
         }
+        animateResizeChange(change, startTransaction, finishTransaction, finishCallback)
+    }
+
+    /**
+     *  Animate an immersive change.
+     *
+     *  As of now, both enter and exit transitions have the same animation, a veiled resize.
+     */
+    fun animateResizeChange(
+        change: TransitionInfo.Change,
+        startTransaction: SurfaceControl.Transaction,
+        finishTransaction: SurfaceControl.Transaction,
+        finishCallback: Transitions.TransitionFinishCallback,
+    ) {
+        val taskId = change.taskInfo!!.taskId
         val leash = change.leash
         val startBounds = change.startAbsBounds
         val endBounds = change.endAbsBounds
+        logD("Animating resize change for task#%d from %s to %s", taskId, startBounds, endBounds)
 
+        startTransaction
+            .setPosition(leash, startBounds.left.toFloat(), startBounds.top.toFloat())
+            .setWindowCrop(leash, startBounds.width(), startBounds.height())
+            .show(leash)
+        onTaskResizeAnimationListener
+            ?.onAnimationStart(taskId, startTransaction, startBounds)
+            ?: startTransaction.apply()
         val updateTransaction = transactionSupplier()
         ValueAnimator.ofObject(rectEvaluator, startBounds, endBounds).apply {
             duration = FULL_IMMERSIVE_ANIM_DURATION_MS
             interpolator = DecelerateInterpolator()
             addListener(
-                onStart = {
-                    startTransaction
-                        .setPosition(leash, startBounds.left.toFloat(), startBounds.top.toFloat())
-                        .setWindowCrop(leash, startBounds.width(), startBounds.height())
-                        .show(leash)
-                    onTaskResizeAnimationListener
-                        ?.onAnimationStart(transitionState.taskId, startTransaction, startBounds)
-                        ?: startTransaction.apply()
-                },
                 onEnd = {
                     finishTransaction
                         .setPosition(leash, endBounds.left.toFloat(), endBounds.top.toFloat())
                         .setWindowCrop(leash, endBounds.width(), endBounds.height())
                         .apply()
-                    onTaskResizeAnimationListener?.onAnimationEnd(transitionState.taskId)
+                    onTaskResizeAnimationListener?.onAnimationEnd(taskId)
                     finishCallback.onTransitionFinished(null /* wct */)
                     clearState()
                 }
@@ -254,7 +287,7 @@
                     .setWindowCrop(leash, rect.width(), rect.height())
                     .apply()
                 onTaskResizeAnimationListener
-                    ?.onBoundsChange(transitionState.taskId, updateTransaction, rect)
+                    ?.onBoundsChange(taskId, updateTransaction, rect)
                     ?: updateTransaction.apply()
             }
             start()
@@ -284,15 +317,20 @@
      * |onTransitionReady|, before this transition actually animates) because drawing decorations
      * depends on whether the task is in full immersive state or not.
      */
-    fun onTransitionReady(transition: IBinder, info: TransitionInfo) {
+    override fun onTransitionReady(
+        transition: IBinder,
+        info: TransitionInfo,
+        startTransaction: SurfaceControl.Transaction,
+        finishTransaction: SurfaceControl.Transaction,
+    ) {
+        logD("onTransitionReady transition=%s", transition)
         // Check if this is a pending external exit transition.
         val pendingExit = pendingExternalExitTransitions
             .firstOrNull { pendingExit -> pendingExit.transition == transition }
         if (pendingExit != null) {
-            pendingExternalExitTransitions.remove(pendingExit)
             if (info.hasTaskChange(taskId = pendingExit.taskId)) {
                 if (desktopRepository.isTaskInFullImmersiveState(pendingExit.taskId)) {
-                    logV("Pending external exit for task ${pendingExit.taskId} verified")
+                    logV("Pending external exit for task#%d verified", pendingExit.taskId)
                     desktopRepository.setTaskInFullImmersiveState(
                         displayId = pendingExit.displayId,
                         taskId = pendingExit.taskId,
@@ -311,7 +349,7 @@
             val state = requireState()
             val startBounds = info.changes.first { c -> c.taskInfo?.taskId == state.taskId }
                 .startAbsBounds
-            logV("Direct move for task ${state.taskId} in ${state.direction} direction verified")
+            logV("Direct move for task#%d in %s direction verified", state.taskId, state.direction)
             when (state.direction) {
                 Direction.ENTER -> {
                     desktopRepository.setTaskInFullImmersiveState(
@@ -343,7 +381,7 @@
             .filter { c -> desktopRepository.isTaskInFullImmersiveState(c.taskInfo!!.taskId) }
             .filter { c -> c.startRotation != c.endRotation }
             .forEach { c ->
-                logV("Detected immersive exit due to rotation for task: ${c.taskInfo!!.taskId}")
+                logV("Detected immersive exit due to rotation for task#%d", c.taskInfo!!.taskId)
                 desktopRepository.setTaskInFullImmersiveState(
                     displayId = c.taskInfo!!.displayId,
                     taskId = c.taskInfo!!.taskId,
@@ -352,6 +390,32 @@
             }
     }
 
+    override fun onTransitionMerged(merged: IBinder, playing: IBinder) {
+        logD("onTransitionMerged merged=%s playing=%s", merged, playing)
+        val pendingExit = pendingExternalExitTransitions
+            .firstOrNull { pendingExit -> pendingExit.transition == merged }
+        if (pendingExit != null) {
+            logV(
+                "Pending exit transition %s for task#%s merged into %s",
+                merged, pendingExit.taskId, playing
+            )
+            pendingExit.transition = playing
+        }
+    }
+
+    override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {
+        logD("onTransitionFinished transition=%s aborted=%b", transition, aborted)
+        val pendingExit = pendingExternalExitTransitions
+            .firstOrNull { pendingExit -> pendingExit.transition == transition }
+        if (pendingExit != null) {
+            logV(
+                "Pending exit transition %s for task#%s finished",
+                transition, pendingExit
+            )
+            pendingExternalExitTransitions.remove(pendingExit)
+        }
+    }
+
     private fun clearState() {
         state = null
     }
@@ -394,7 +458,7 @@
     data class ExternalPendingExit(
         val taskId: Int,
         val displayId: Int,
-        val transition: IBinder,
+        var transition: IBinder,
     )
 
     private enum class Direction {
@@ -405,6 +469,10 @@
         ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
     }
 
+    private fun logD(msg: String, vararg arguments: Any?) {
+        ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+    }
+
     private companion object {
         private const val TAG = "DesktopImmersive"
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
index df9fc59..dba46d0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
@@ -138,7 +138,7 @@
 
     private fun isLastDesktopTask(change: TransitionInfo.Change): Boolean =
         change.taskInfo?.let {
-            desktopRepository.getActiveNonMinimizedTaskCount(it.displayId) == 1
+            desktopRepository.getExpandedTaskCount(it.displayId) == 1
         } ?: false
 
     private fun findCloseDesktopTaskChange(info: TransitionInfo): TransitionInfo.Change? {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
index 85a3126..5998dc8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
@@ -260,11 +260,11 @@
         ArraySet(desktopTaskDataByDisplayId[displayId]?.minimizedTasks)
 
     /** Returns all active non-minimized tasks for [displayId] ordered from top to bottom. */
-    fun getActiveNonMinimizedOrderedTasks(displayId: Int): List<Int> =
+    fun getExpandedTasksOrdered(displayId: Int): List<Int> =
         getFreeformTasksInZOrder(displayId).filter { !isMinimizedTask(it) }
 
     /** Returns the count of active non-minimized tasks for [displayId]. */
-    fun getActiveNonMinimizedTaskCount(displayId: Int): Int {
+    fun getExpandedTaskCount(displayId: Int): Int {
         return getActiveTasks(displayId).count { !isMinimizedTask(it) }
     }
 
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 69776cd..77fb4b4 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
@@ -48,6 +48,7 @@
 import android.view.KeyEvent
 import android.view.MotionEvent
 import android.view.SurfaceControl
+import android.view.SurfaceControl.Transaction
 import android.view.WindowManager.TRANSIT_CHANGE
 import android.view.WindowManager.TRANSIT_CLOSE
 import android.view.WindowManager.TRANSIT_NONE
@@ -59,6 +60,7 @@
 import android.window.DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS
 import android.window.RemoteTransition
 import android.window.TransitionInfo
+import android.window.TransitionInfo.Change
 import android.window.TransitionRequestInfo
 import android.window.WindowContainerTransaction
 import androidx.annotation.BinderThread
@@ -115,6 +117,7 @@
 import com.android.wm.shell.transition.FocusTransitionObserver
 import com.android.wm.shell.transition.OneShotRemoteHandler
 import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.transition.Transitions.TransitionFinishCallback
 import com.android.wm.shell.windowdecor.DragPositioningCallbackUtility
 import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
 import com.android.wm.shell.windowdecor.OnTaskRepositionAnimationListener
@@ -146,7 +149,7 @@
     private val desktopModeDragAndDropTransitionHandler: DesktopModeDragAndDropTransitionHandler,
     private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
     private val dragToDesktopTransitionHandler: DragToDesktopTransitionHandler,
-    private val immersiveTransitionHandler: DesktopFullImmersiveTransitionHandler,
+    private val desktopImmersiveController: DesktopImmersiveController,
     private val taskRepository: DesktopRepository,
     private val desktopModeLoggerTransitionObserver: DesktopModeLoggerTransitionObserver,
     private val launchAdjacentController: LaunchAdjacentController,
@@ -252,7 +255,7 @@
         toggleResizeDesktopTaskTransitionHandler.setOnTaskResizeAnimationListener(listener)
         enterDesktopTaskTransitionHandler.setOnTaskResizeAnimationListener(listener)
         dragToDesktopTransitionHandler.onTaskResizeAnimationListener = listener
-        immersiveTransitionHandler.onTaskResizeAnimationListener = listener
+        desktopImmersiveController.onTaskResizeAnimationListener = listener
     }
 
     fun setOnTaskRepositionAnimationListener(listener: OnTaskRepositionAnimationListener) {
@@ -372,8 +375,11 @@
         // TODO(342378842): Instead of using default display, support multiple displays
         val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask(
             DEFAULT_DISPLAY, wct, taskId)
-        val runOnTransit = immersiveTransitionHandler
-            .exitImmersiveIfApplicable(wct, DEFAULT_DISPLAY)
+        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
+            wct = wct,
+            displayId = DEFAULT_DISPLAY,
+            excludeTaskId = taskId,
+        )
         wct.startTask(
             taskId,
             ActivityOptions.makeBasic().apply {
@@ -400,7 +406,11 @@
         }
         logV("moveRunningTaskToDesktop taskId=%d", task.taskId)
         exitSplitIfApplicable(wct, task)
-        val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable(wct, task.displayId)
+        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
+            wct = wct,
+            displayId = task.displayId,
+            excludeTaskId = task.taskId,
+        )
         // Bring other apps to front first
         val taskToMinimize =
             bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
@@ -445,7 +455,7 @@
         val taskToMinimize =
             bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId)
         addMoveToDesktopChanges(wct, taskInfo)
-        val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable(
+        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
             wct, taskInfo.displayId)
         val transition = dragToDesktopTransitionHandler.finishDragToDesktopTransition(wct)
         transition?.let {
@@ -492,7 +502,7 @@
                 taskId
             )
         )
-        return immersiveTransitionHandler.exitImmersiveIfApplicable(wct, taskInfo)
+        return desktopImmersiveController.exitImmersiveIfApplicable(wct, taskInfo)
     }
 
     fun minimizeTask(taskInfo: RunningTaskInfo) {
@@ -505,7 +515,7 @@
             removeWallpaperActivity(wct)
         }
         // Notify immersive handler as it might need to exit immersive state.
-        val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable(wct, taskInfo)
+        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(wct, taskInfo)
 
         wct.reorder(taskInfo.token, false)
         val transition = freeformTaskTransitionStarter.startMinimizedModeTransition(wct)
@@ -609,8 +619,11 @@
         logV("moveBackgroundTaskToFront taskId=%s", taskId)
         val wct = WindowContainerTransaction()
         // TODO: b/342378842 - Instead of using default display, support multiple displays
-        val runOnTransit = immersiveTransitionHandler
-            .exitImmersiveIfApplicable(wct, DEFAULT_DISPLAY)
+        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
+            wct = wct,
+            displayId = DEFAULT_DISPLAY,
+            excludeTaskId = taskId,
+        )
         wct.startTask(
             taskId,
             ActivityOptions.makeBasic().apply {
@@ -632,8 +645,11 @@
         logV("moveTaskToFront taskId=%s", taskInfo.taskId)
         val wct = WindowContainerTransaction()
         wct.reorder(taskInfo.token, true /* onTop */, true /* includingParents */)
-        val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable(
-            wct, taskInfo.displayId)
+        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
+            wct = wct,
+            displayId = taskInfo.displayId,
+            excludeTaskId = taskInfo.taskId,
+        )
         val transition =
             startLaunchTransition(TRANSIT_TO_FRONT, wct, taskInfo.taskId, remoteTransition)
         runOnTransit?.invoke(transition)
@@ -646,7 +662,7 @@
         remoteTransition: RemoteTransition?,
     ): IBinder {
         val taskToMinimize: RunningTaskInfo? =
-            addAndGetMinimizeChangesIfNeeded(DEFAULT_DISPLAY, wct, taskId)
+            addAndGetMinimizeChanges(DEFAULT_DISPLAY, wct, taskId)
         if (remoteTransition == null) {
             val t = transitions.startTransition(transitionType, wct, null /* handler */)
             addPendingMinimizeTransition(t, taskToMinimize)
@@ -736,12 +752,12 @@
 
     private fun moveDesktopTaskToFullImmersive(taskInfo: RunningTaskInfo) {
         check(taskInfo.isFreeform) { "Task must already be in freeform" }
-        immersiveTransitionHandler.moveTaskToImmersive(taskInfo)
+        desktopImmersiveController.moveTaskToImmersive(taskInfo)
     }
 
     private fun exitDesktopTaskFromFullImmersive(taskInfo: RunningTaskInfo) {
         check(taskInfo.isFreeform) { "Task must already be in freeform" }
-        immersiveTransitionHandler.moveTaskToNonImmersive(taskInfo)
+        desktopImmersiveController.moveTaskToNonImmersive(taskInfo)
     }
 
     /**
@@ -856,7 +872,7 @@
         excludeTaskId: Int? = null,
     ): Boolean {
         val doesAnyTaskRequireTaskbarRounding =
-            taskRepository.getActiveNonMinimizedOrderedTasks(displayId)
+            taskRepository.getExpandedTasksOrdered(displayId)
                 // exclude current task since maximize/restore transition has not taken place yet.
                 .filterNot { taskId -> taskId == excludeTaskId }
                 .any { taskId ->
@@ -1034,23 +1050,23 @@
             addWallpaperActivity(wct)
         }
 
-        val nonMinimizedTasksOrderedFrontToBack =
-            taskRepository.getActiveNonMinimizedOrderedTasks(displayId)
+        val expandedTasksOrderedFrontToBack =
+            taskRepository.getExpandedTasksOrdered(displayId)
         // If we're adding a new Task we might need to minimize an old one
         // TODO(b/365725441): Handle non running task minimization
         val taskToMinimize: RunningTaskInfo? =
             if (newTaskIdInFront != null && desktopTasksLimiter.isPresent) {
                 desktopTasksLimiter
                     .get()
-                    .getTaskToMinimizeIfNeeded(
-                        nonMinimizedTasksOrderedFrontToBack,
+                    .getTaskToMinimize(
+                        expandedTasksOrderedFrontToBack,
                         newTaskIdInFront
                     )
             } else {
                 null
             }
 
-        nonMinimizedTasksOrderedFrontToBack
+        expandedTasksOrderedFrontToBack
             // If there is a Task to minimize, let it stay behind the Home Task
             .filter { taskId -> taskId != taskToMinimize?.taskId }
             .reversed() // Start from the back so the front task is brought forward last
@@ -1220,6 +1236,67 @@
         return result
     }
 
+    /** Whether the given [change] in the [transition] is a known desktop change. */
+    fun isDesktopChange(
+        transition: IBinder,
+        change: TransitionInfo.Change,
+    ): Boolean {
+        // Only the immersive controller is currently involved in mixed transitions.
+        return Flags.enableFullyImmersiveInDesktop()
+                && desktopImmersiveController.isImmersiveChange(transition, change)
+    }
+
+    /**
+     * Whether the given transition [info] will potentially include a desktop change, in which
+     * case the transition should be treated as mixed so that the change is in part animated by
+     * one of the desktop transition handlers.
+     */
+    fun shouldPlayDesktopAnimation(info: TransitionRequestInfo): Boolean {
+        // Only immersive mixed transition are currently supported.
+        if (!Flags.enableFullyImmersiveInDesktop()) return false
+        val triggerTask = info.triggerTask ?: return false
+        if (!isDesktopModeShowing(triggerTask.displayId)) {
+            return false
+        }
+        if (!TransitionUtil.isOpeningType(info.type)) {
+            return false
+        }
+        taskRepository.getTaskInFullImmersiveState(displayId = triggerTask.displayId)
+            ?: return false
+        return when {
+            triggerTask.isFullscreen -> {
+                // Trigger fullscreen task will enter desktop, so any existing immersive task
+                // should exit.
+                shouldFullscreenTaskLaunchSwitchToDesktop(triggerTask)
+            }
+            triggerTask.isFreeform -> {
+                // Trigger freeform task will enter desktop, so any existing immersive task should
+                // exit.
+                !shouldFreeformTaskLaunchSwitchToFullscreen(triggerTask)
+            }
+            else -> false
+        }
+    }
+
+    /** Animate a desktop change found in a mixed transitions. */
+    fun animateDesktopChange(
+        transition: IBinder,
+        change: Change,
+        startTransaction: Transaction,
+        finishTransaction: Transaction,
+        finishCallback: TransitionFinishCallback,
+    ) {
+        if (!desktopImmersiveController.isImmersiveChange(transition, change)) {
+            throw IllegalStateException("Only immersive changes support desktop mixed transitions")
+        }
+        desktopImmersiveController.animateResizeChange(
+            change,
+            startTransaction,
+            finishTransaction,
+            finishCallback
+        )
+    }
+
     private fun taskContainsDragAndDropCookie(taskInfo: RunningTaskInfo?) =
         taskInfo?.launchCookies?.any { it == dragAndDropFullscreenCookie } ?: false
 
@@ -1266,8 +1343,11 @@
             wct.startTask(requestedTaskId, options.toBundle())
             val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask(
                 callingTask.displayId, wct, requestedTaskId)
-            val runOnTransit = immersiveTransitionHandler
-                .exitImmersiveIfApplicable(wct, callingTask.displayId)
+            val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
+                wct = wct,
+                displayId = callingTask.displayId,
+                excludeTaskId = requestedTaskId,
+            )
             val transition = transitions.startTransition(TRANSIT_OPEN, wct, null)
             addPendingMinimizeTransition(transition, taskToMinimize)
             runOnTransit?.invoke(transition)
@@ -1376,7 +1456,7 @@
             return null
         }
         val wct = WindowContainerTransaction()
-        if (!isDesktopModeShowing(task.displayId)) {
+        if (shouldFreeformTaskLaunchSwitchToFullscreen(task)) {
             logD("Bring desktop tasks to front on transition=taskId=%d", task.taskId)
             if (taskRepository.isActiveTask(task.taskId) && !forceEnterDesktop(task.displayId)) {
                 // We are outside of desktop mode and already existing desktop task is being
@@ -1407,9 +1487,9 @@
         }
         // Desktop Mode is showing and we're launching a new Task:
         // 1) Exit immersive if needed.
-        immersiveTransitionHandler.exitImmersiveIfApplicable(transition, wct, task.displayId)
+        desktopImmersiveController.exitImmersiveIfApplicable(transition, wct, task.displayId)
         // 2) minimize a Task if needed.
-        val taskToMinimize = addAndGetMinimizeChangesIfNeeded(task.displayId, wct, task.taskId)
+        val taskToMinimize = addAndGetMinimizeChanges(task.displayId, wct, task.taskId)
         if (taskToMinimize != null) {
             addPendingMinimizeTransition(transition, taskToMinimize)
             return wct
@@ -1422,7 +1502,7 @@
         transition: IBinder
     ): WindowContainerTransaction? {
         logV("handleFullscreenTaskLaunch")
-        if (isDesktopModeShowing(task.displayId) || forceEnterDesktop(task.displayId)) {
+        if (shouldFullscreenTaskLaunchSwitchToDesktop(task)) {
             logD("Switch fullscreen task to freeform on transition: taskId=%d", task.taskId)
             return WindowContainerTransaction().also { wct ->
                 addMoveToDesktopChanges(wct, task)
@@ -1436,9 +1516,9 @@
                 // Desktop Mode is already showing and we're launching a new Task - we might need to
                 // minimize another Task.
                 val taskToMinimize =
-                    addAndGetMinimizeChangesIfNeeded(task.displayId, wct, task.taskId)
+                    addAndGetMinimizeChanges(task.displayId, wct, task.taskId)
                 addPendingMinimizeTransition(transition, taskToMinimize)
-                immersiveTransitionHandler.exitImmersiveIfApplicable(
+                desktopImmersiveController.exitImmersiveIfApplicable(
                     transition, wct, task.displayId
                 )
             }
@@ -1446,6 +1526,12 @@
         return null
     }
 
+    private fun shouldFreeformTaskLaunchSwitchToFullscreen(task: RunningTaskInfo): Boolean =
+        !isDesktopModeShowing(task.displayId)
+
+    private fun shouldFullscreenTaskLaunchSwitchToDesktop(task: RunningTaskInfo): Boolean =
+        isDesktopModeShowing(task.displayId) || forceEnterDesktop(task.displayId)
+
     /**
      * If a task is not compatible with desktop mode freeform, it should always be launched in
      * fullscreen.
@@ -1564,7 +1650,7 @@
         val stableBounds = Rect()
         displayLayout.getStableBoundsForDesktopMode(stableBounds)
 
-        val activeTasks = taskRepository.getActiveNonMinimizedOrderedTasks(displayId)
+        val activeTasks = taskRepository.getExpandedTasksOrdered(displayId)
         activeTasks.firstOrNull()?.let { activeTask ->
             shellTaskOrganizer.getRunningTaskInfo(activeTask)?.let {
                 cascadeWindow(context.resources, stableBounds,
@@ -1593,7 +1679,7 @@
     }
 
     /** Returns the ID of the Task that will be minimized, or null if no task will be minimized. */
-    private fun addAndGetMinimizeChangesIfNeeded(
+    private fun addAndGetMinimizeChanges(
         displayId: Int,
         wct: WindowContainerTransaction,
         newTaskId: Int
@@ -1601,7 +1687,7 @@
         if (!desktopTasksLimiter.isPresent) return null
         return desktopTasksLimiter
             .get()
-            .addAndGetMinimizeTaskChangesIfNeeded(displayId, wct, newTaskId)
+            .addAndGetMinimizeTaskChanges(displayId, wct, newTaskId)
     }
 
     private fun addPendingMinimizeTransition(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
index d6b7212..cd28a4f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
@@ -30,7 +30,7 @@
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.ShellTaskOrganizer
-import com.android.wm.shell.protolog.ShellProtoLogGroup
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
 import com.android.wm.shell.shared.annotations.ShellMainThread
 import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.transition.Transitions.TransitionObserver
@@ -57,13 +57,11 @@
 
     init {
         require(maxTasksLimit > 0) {
-            "DesktopTasksLimiter should not be created with a maxTasksLimit at 0 or less. " +
-                    "Current value: $maxTasksLimit."
+            "DesktopTasksLimiter: maxTasksLimit should be greater than 0. Current value: $maxTasksLimit."
         }
         transitions.registerObserver(minimizeTransitionObserver)
         taskRepository.addActiveTaskListener(leftoverMinimizedTasksRemover)
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
-            "DesktopTasksLimiter: starting limiter with a maximum of %d tasks", maxTasksLimit)
+        logV("Starting limiter with a maximum of %d tasks", maxTasksLimit)
     }
 
     private data class TaskDetails(
@@ -88,20 +86,14 @@
             finishTransaction: SurfaceControl.Transaction
         ) {
             val taskToMinimize = pendingTransitionTokensAndTasks.remove(transition) ?: return
-
             if (!taskRepository.isActiveTask(taskToMinimize.taskId)) return
-
-            if (!isTaskReorderedToBackOrInvisible(info, taskToMinimize)) {
-                ProtoLog.v(
-                        ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
-                        "DesktopTasksLimiter: task %d is not reordered to back nor invis",
-                        taskToMinimize.taskId)
+            if (!isTaskReadyForMinimize(info, taskToMinimize)) {
+                logV("task %d is not reordered to back nor invis", taskToMinimize.taskId)
                 return
             }
-
             taskToMinimize.transitionInfo = info
             activeTransitionTokensAndTasks[transition] = taskToMinimize
-            this@DesktopTasksLimiter.markTaskMinimized(
+            this@DesktopTasksLimiter.minimizeTask(
                     taskToMinimize.displayId, taskToMinimize.taskId)
         }
 
@@ -109,18 +101,15 @@
          * Returns whether the Task [taskDetails] is being reordered to the back in the transition
          * [info], or is already invisible.
          *
-         * This check can be used to double-check that a task was indeed minimized before
-         * marking it as such.
+         * This check confirms a task should be minimized before minimizing it.
          */
-        private fun isTaskReorderedToBackOrInvisible(
-                info: TransitionInfo,
-                taskDetails: TaskDetails
+        private fun isTaskReadyForMinimize(
+            info: TransitionInfo,
+            taskDetails: TaskDetails
         ): Boolean {
             val taskChange = info.changes.find { change ->
                 change.taskInfo?.taskId == taskDetails.taskId }
-            if (taskChange == null) {
-                return !taskRepository.isVisibleTask(taskDetails.taskId)
-            }
+            if (taskChange == null) return !taskRepository.isVisibleTask(taskDetails.taskId)
             return taskChange.mode == TRANSIT_TO_BACK
         }
 
@@ -145,9 +134,7 @@
         }
 
         override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {
-            ProtoLog.v(
-                    ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
-                    "DesktopTasksLimiter: transition %s finished", transition)
+            logV("transition %s finished", transition)
             if (activeTransitionTokensAndTasks.remove(transition) != null) {
                 if (aborted) {
                     interactionJankMonitor.cancel(CUJ_DESKTOP_MODE_MINIMIZE_WINDOW)
@@ -170,18 +157,11 @@
         }
 
         fun removeLeftoverMinimizedTasks(displayId: Int, wct: WindowContainerTransaction) {
-            if (taskRepository.getActiveNonMinimizedOrderedTasks(displayId).isNotEmpty()) {
-                return
-            }
+            if (taskRepository.getExpandedTasksOrdered(displayId).isNotEmpty()) return
             val remainingMinimizedTasks = taskRepository.getMinimizedTasks(displayId)
-            if (remainingMinimizedTasks.isEmpty()) {
-                return
-            }
-            ProtoLog.v(
-                ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
-                "DesktopTasksLimiter: removing leftover minimized tasks: %s",
-                remainingMinimizedTasks,
-            )
+            if (remainingMinimizedTasks.isEmpty()) return
+
+            logV("Removing leftover minimized tasks: %s", remainingMinimizedTasks)
             remainingMinimizedTasks.forEach { taskIdToRemove ->
                 val taskToRemove = shellTaskOrganizer.getRunningTaskInfo(taskIdToRemove)
                 if (taskToRemove != null) {
@@ -192,35 +172,30 @@
     }
 
     /**
-     * Mark [taskId], which must be on [displayId], as minimized, this should only be done after the
-     * corresponding transition has finished so we don't minimize the task if the transition fails.
+     * Mark task with [taskId] on [displayId] as minimized.
+     *
+     * This should be after the corresponding transition has finished so we don't
+     * minimize the task if the transition fails.
      */
-    private fun markTaskMinimized(displayId: Int, taskId: Int) {
-        ProtoLog.v(
-                ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
-                "DesktopTasksLimiter: marking %d as minimized", taskId)
+    private fun minimizeTask(displayId: Int, taskId: Int) {
+        logV("Minimize taskId=%d, displayId=%d", taskId, displayId)
         taskRepository.minimizeTask(displayId, taskId)
     }
 
     /**
-     * Add a minimize-transition to [wct] if adding [newFrontTaskInfo] brings us over the task
+     * Adds a minimize-transition to [wct] if adding [newFrontTaskInfo] crosses task
      * limit, returning the task to minimize.
-     *
-     * The task must be on [displayId].
      */
-    fun addAndGetMinimizeTaskChangesIfNeeded(
+    fun addAndGetMinimizeTaskChanges(
             displayId: Int,
             wct: WindowContainerTransaction,
             newFrontTaskId: Int,
     ): RunningTaskInfo? {
-        ProtoLog.v(
-                ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
-                "DesktopTasksLimiter: addMinimizeBackTaskChangesIfNeeded, newFrontTask=%d",
-            newFrontTaskId)
-        val newTaskListOrderedFrontToBack = createOrderedTaskListWithGivenTaskInFront(
-                taskRepository.getActiveNonMinimizedOrderedTasks(displayId),
-            newFrontTaskId)
-        val taskToMinimize = getTaskToMinimizeIfNeeded(newTaskListOrderedFrontToBack)
+        logV("addAndGetMinimizeTaskChanges, newFrontTask=%d", newFrontTaskId)
+        // This list is ordered from front to back.
+        val newTaskOrderedList = createOrderedTaskListWithNewTask(
+            taskRepository.getExpandedTasksOrdered(displayId), newFrontTaskId)
+        val taskToMinimize = getTaskToMinimize(newTaskOrderedList)
         if (taskToMinimize != null) {
             wct.reorder(taskToMinimize.token, false /* onTop */)
             return taskToMinimize
@@ -229,7 +204,7 @@
     }
 
     /**
-     * Add a pending minimize transition change, to update the list of minimized apps once the
+     * Add a pending minimize transition change to update the list of minimized apps once the
      * transition goes through.
      */
     fun addPendingMinimizeChange(transition: IBinder, displayId: Int, taskId: Int) {
@@ -238,51 +213,47 @@
     }
 
     /**
-     * Returns the Task to minimize given 1. a list of visible tasks ordered from front to back and
-     * 2. a new task placed in front of all the others.
+     * Returns the minimized task from the list of visible tasks ordered from front to back with
+     * the new task placed in front of other tasks.
      */
-    fun getTaskToMinimizeIfNeeded(
-            visibleFreeformTaskIdsOrderedFrontToBack: List<Int>,
+    fun getTaskToMinimize(
+            visibleOrderedTasks: List<Int>,
             newTaskIdInFront: Int
-    ): RunningTaskInfo? {
-        return getTaskToMinimizeIfNeeded(
-                createOrderedTaskListWithGivenTaskInFront(
-                        visibleFreeformTaskIdsOrderedFrontToBack, newTaskIdInFront))
-    }
+    ): RunningTaskInfo? =
+        getTaskToMinimize(createOrderedTaskListWithNewTask(visibleOrderedTasks, newTaskIdInFront))
 
     /** Returns the Task to minimize given a list of visible tasks ordered from front to back. */
-    fun getTaskToMinimizeIfNeeded(
-            visibleFreeformTaskIdsOrderedFrontToBack: List<Int>
-    ): RunningTaskInfo? {
-        if (visibleFreeformTaskIdsOrderedFrontToBack.size <= maxTasksLimit) {
-            ProtoLog.v(
-                    ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
-                    "DesktopTasksLimiter: no need to minimize; tasks below limit")
-            // No need to minimize anything
+    fun getTaskToMinimize(visibleOrderedTasks: List<Int>): RunningTaskInfo? {
+        if (visibleOrderedTasks.size <= maxTasksLimit) {
+            logV("No need to minimize; tasks below limit")
             return null
         }
-        val taskIdToMinimize = visibleFreeformTaskIdsOrderedFrontToBack.last()
+        val taskIdToMinimize = visibleOrderedTasks.last()
         val taskToMinimize =
                 shellTaskOrganizer.getRunningTaskInfo(taskIdToMinimize)
         if (taskToMinimize == null) {
-            ProtoLog.e(
-                    ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
-                    "DesktopTasksLimiter: taskToMinimize(taskId = %d) == null",
-                    taskIdToMinimize,
-                )
+            logE("taskToMinimize(taskId = %d) == null", taskIdToMinimize)
             return null
         }
         return taskToMinimize
     }
 
-    private fun createOrderedTaskListWithGivenTaskInFront(
-            existingTaskIdsOrderedFrontToBack: List<Int>,
-            newTaskId: Int
-    ): List<Int> {
-        return listOf(newTaskId) +
-                existingTaskIdsOrderedFrontToBack.filter { taskId -> taskId != newTaskId }
-    }
+    private fun createOrderedTaskListWithNewTask(
+        orderedTaskIds: List<Int>, newTaskId: Int): List<Int> =
+            listOf(newTaskId) + orderedTaskIds.filter { taskId -> taskId != newTaskId }
 
     @VisibleForTesting
     fun getTransitionObserver(): TransitionObserver = minimizeTransitionObserver
-}
\ No newline at end of file
+
+    private fun logV(msg: String, vararg arguments: Any?) {
+        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+    }
+
+    private fun logE(msg: String, vararg arguments: Any?) {
+        ProtoLog.e(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+    }
+
+    private companion object {
+        const val TAG = "DesktopTasksLimiter"
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
index 771573d..7631ece 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
@@ -28,7 +28,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.window.flags.Flags;
-import com.android.wm.shell.desktopmode.DesktopFullImmersiveTransitionHandler;
+import com.android.wm.shell.desktopmode.DesktopImmersiveController;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.FocusTransitionObserver;
 import com.android.wm.shell.transition.Transitions;
@@ -48,7 +48,7 @@
  */
 public class FreeformTaskTransitionObserver implements Transitions.TransitionObserver {
     private final Transitions mTransitions;
-    private final Optional<DesktopFullImmersiveTransitionHandler> mImmersiveTransitionHandler;
+    private final Optional<DesktopImmersiveController> mDesktopImmersiveController;
     private final WindowDecorViewModel mWindowDecorViewModel;
     private final Optional<TaskChangeListener> mTaskChangeListener;
     private final FocusTransitionObserver mFocusTransitionObserver;
@@ -60,12 +60,12 @@
             Context context,
             ShellInit shellInit,
             Transitions transitions,
-            Optional<DesktopFullImmersiveTransitionHandler> immersiveTransitionHandler,
+            Optional<DesktopImmersiveController> desktopImmersiveController,
             WindowDecorViewModel windowDecorViewModel,
             Optional<TaskChangeListener> taskChangeListener,
             FocusTransitionObserver focusTransitionObserver) {
         mTransitions = transitions;
-        mImmersiveTransitionHandler = immersiveTransitionHandler;
+        mDesktopImmersiveController = desktopImmersiveController;
         mWindowDecorViewModel = windowDecorViewModel;
         mTaskChangeListener = taskChangeListener;
         mFocusTransitionObserver = focusTransitionObserver;
@@ -89,7 +89,8 @@
             // TODO(b/367268953): Remove when DesktopTaskListener is introduced and the repository
             //  is updated from there **before** the |mWindowDecorViewModel| methods are invoked.
             //  Otherwise window decoration relayout won't run with the immersive state up to date.
-            mImmersiveTransitionHandler.ifPresent(h -> h.onTransitionReady(transition, info));
+            mDesktopImmersiveController.ifPresent(h ->
+                    h.onTransitionReady(transition, info, startT, finishT));
         }
         // Update focus state first to ensure the correct state can be queried from listeners.
         // TODO(371503964): Remove this once the unified task repository is ready.
@@ -194,10 +195,20 @@
     }
 
     @Override
-    public void onTransitionStarting(@NonNull IBinder transition) {}
+    public void onTransitionStarting(@NonNull IBinder transition) {
+        if (Flags.enableFullyImmersiveInDesktop()) {
+            // TODO(b/367268953): Remove when DesktopTaskListener is introduced.
+            mDesktopImmersiveController.ifPresent(h -> h.onTransitionStarting(transition));
+        }
+    }
 
     @Override
     public void onTransitionMerged(@NonNull IBinder merged, @NonNull IBinder playing) {
+        if (Flags.enableFullyImmersiveInDesktop()) {
+            // TODO(b/367268953): Remove when DesktopTaskListener is introduced.
+            mDesktopImmersiveController.ifPresent(h -> h.onTransitionMerged(merged, playing));
+        }
+
         final List<ActivityManager.RunningTaskInfo> infoOfMerged =
                 mTransitionToTaskInfo.get(merged);
         if (infoOfMerged == null) {
@@ -218,6 +229,11 @@
 
     @Override
     public void onTransitionFinished(@NonNull IBinder transition, boolean aborted) {
+        if (Flags.enableFullyImmersiveInDesktop()) {
+            // TODO(b/367268953): Remove when DesktopTaskListener is introduced.
+            mDesktopImmersiveController.ifPresent(h -> h.onTransitionFinished(transition, aborted));
+        }
+
         final List<ActivityManager.RunningTaskInfo> taskInfo =
                 mTransitionToTaskInfo.getOrDefault(transition, Collections.emptyList());
         mTransitionToTaskInfo.remove(transition);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 766a6b3..0d89f75 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -83,8 +83,11 @@
         /** Both the display and split-state (enter/exit) is changing */
         static final int TYPE_DISPLAY_AND_SPLIT_CHANGE = 2;
 
-        /** Pip was entered while handling an intent with its own remoteTransition. */
-        static final int TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE = 3;
+        /**
+         * While handling an intent with its own remoteTransition, a PIP enter or Desktop immersive
+         * exit change is found.
+         */
+        static final int TYPE_OPTIONS_REMOTE_AND_PIP_OR_DESKTOP_CHANGE = 3;
 
         /** Recents transition while split-screen foreground. */
         static final int TYPE_RECENTS_DURING_SPLIT = 4;
@@ -110,6 +113,9 @@
         /** The display changes when pip is entering. */
         static final int TYPE_ENTER_PIP_WITH_DISPLAY_CHANGE = 11;
 
+        /** Open transition during a desktop session. */
+        static final int TYPE_OPEN_IN_DESKTOP = 12;
+
         /** The default animation for this mixed transition. */
         static final int ANIM_TYPE_DEFAULT = 0;
 
@@ -296,7 +302,7 @@
                 return null;
             }
             final MixedTransition mixed = createDefaultMixedTransition(
-                    MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE, transition);
+                    MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_OR_DESKTOP_CHANGE, transition);
             mixed.mLeftoversHandler = handler.first;
             mActiveTransitions.add(mixed);
             if (mixed.mLeftoversHandler != mPlayer.getRemoteTransitionHandler()) {
@@ -334,6 +340,20 @@
                         MixedTransition.TYPE_UNFOLD, transition));
             }
             return wct;
+        } else if (mDesktopTasksController != null
+                && mDesktopTasksController.shouldPlayDesktopAnimation(request)) {
+            final Pair<Transitions.TransitionHandler, WindowContainerTransaction> handler =
+                    mPlayer.dispatchRequest(transition, request, /* skip= */ this);
+            if (handler == null) {
+                return null;
+            }
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a desktop request, so"
+                    + " treat it as Mixed. handler=%s", handler.first);
+            final MixedTransition mixed = createDefaultMixedTransition(
+                    MixedTransition.TYPE_OPEN_IN_DESKTOP, transition);
+            mixed.mLeftoversHandler = handler.first;
+            mActiveTransitions.add(mixed);
+            return handler.second;
         }
         return null;
     }
@@ -341,7 +361,7 @@
     private DefaultMixedTransition createDefaultMixedTransition(int type, IBinder transition) {
         return new DefaultMixedTransition(
                 type, transition, mPlayer, this, mPipHandler, mSplitHandler, mKeyguardHandler,
-                mUnfoldHandler, mActivityEmbeddingController);
+                mUnfoldHandler, mActivityEmbeddingController, mDesktopTasksController);
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
index c8921d2..3d3de88 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
@@ -30,6 +30,7 @@
 
 import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
+import com.android.wm.shell.desktopmode.DesktopTasksController;
 import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -39,15 +40,19 @@
 class DefaultMixedTransition extends DefaultMixedHandler.MixedTransition {
     private final UnfoldTransitionHandler mUnfoldHandler;
     private final ActivityEmbeddingController mActivityEmbeddingController;
+    @Nullable
+    private final DesktopTasksController mDesktopTasksController;
 
     DefaultMixedTransition(int type, IBinder transition, Transitions player,
             MixedTransitionHandler mixedHandler, PipTransitionController pipHandler,
             StageCoordinator splitHandler, KeyguardTransitionHandler keyguardHandler,
             UnfoldTransitionHandler unfoldHandler,
-            ActivityEmbeddingController activityEmbeddingController) {
+            ActivityEmbeddingController activityEmbeddingController,
+            @Nullable DesktopTasksController desktopTasksController) {
         super(type, transition, player, mixedHandler, pipHandler, splitHandler, keyguardHandler);
         mUnfoldHandler = unfoldHandler;
         mActivityEmbeddingController = activityEmbeddingController;
+        mDesktopTasksController = desktopTasksController;
 
         switch (type) {
             case TYPE_UNFOLD:
@@ -57,7 +62,8 @@
             case TYPE_ENTER_PIP_FROM_ACTIVITY_EMBEDDING:
             case TYPE_ENTER_PIP_FROM_SPLIT:
             case TYPE_KEYGUARD:
-            case TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE:
+            case TYPE_OPTIONS_REMOTE_AND_PIP_OR_DESKTOP_CHANGE:
+            case TYPE_OPEN_IN_DESKTOP:
             default:
                 break;
         }
@@ -85,11 +91,14 @@
             case TYPE_KEYGUARD ->
                     animateKeyguard(this, info, startTransaction, finishTransaction, finishCallback,
                             mKeyguardHandler, mPipHandler);
-            case TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE ->
-                    animateOpenIntentWithRemoteAndPip(transition, info, startTransaction,
+            case TYPE_OPTIONS_REMOTE_AND_PIP_OR_DESKTOP_CHANGE ->
+                    animateOpenIntentWithRemoteAndPipOrDesktop(transition, info, startTransaction,
                             finishTransaction, finishCallback);
             case TYPE_UNFOLD ->
                     animateUnfold(info, startTransaction, finishTransaction, finishCallback);
+            case TYPE_OPEN_IN_DESKTOP ->
+                    animateOpenInDesktop(
+                            transition, info, startTransaction, finishTransaction, finishCallback);
             default -> throw new IllegalStateException(
                     "Starting default mixed animation with unknown or illegal type: " + mType);
         };
@@ -146,31 +155,34 @@
         return true;
     }
 
-    private boolean animateOpenIntentWithRemoteAndPip(
+    private boolean animateOpenIntentWithRemoteAndPipOrDesktop(
             @NonNull IBinder transition, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Mixed transition for opening an intent"
-                + " with a remote transition and PIP #%d", info.getDebugId());
-        boolean handledToPip = tryAnimateOpenIntentWithRemoteAndPip(
+                + " with a remote transition and PIP or Desktop #%d", info.getDebugId());
+        boolean handledToPipOrDesktop = tryAnimateOpenIntentWithRemoteAndPipOrDesktop(
                 info, startTransaction, finishTransaction, finishCallback);
         // Consume the transition on remote handler if the leftover handler already handle this
         // transition. And if it cannot, the transition will be handled by remote handler, so don't
         // consume here.
-        // Need to check leftOverHandler as it may change in #animateOpenIntentWithRemoteAndPip
-        if (handledToPip && mHasRequestToRemote
+        // Need to check leftOverHandler as it may change in
+        // #animateOpenIntentWithRemoteAndPipOrDesktop
+        if (handledToPipOrDesktop && mHasRequestToRemote
                 && mLeftoversHandler != mPlayer.getRemoteTransitionHandler()) {
             mPlayer.getRemoteTransitionHandler().onTransitionConsumed(transition, false, null);
         }
-        return handledToPip;
+        return handledToPipOrDesktop;
     }
 
-    private boolean tryAnimateOpenIntentWithRemoteAndPip(
+    private boolean tryAnimateOpenIntentWithRemoteAndPipOrDesktop(
             @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+                "tryAnimateOpenIntentWithRemoteAndPipOrDesktop");
         TransitionInfo.Change pipChange = null;
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             TransitionInfo.Change change = info.getChanges().get(i);
@@ -183,13 +195,31 @@
                 info.getChanges().remove(i);
             }
         }
+        TransitionInfo.Change desktopChange = null;
+        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+            TransitionInfo.Change change = info.getChanges().get(i);
+            if (mDesktopTasksController != null
+                    && mDesktopTasksController.isDesktopChange(mTransition, change)) {
+                if (desktopChange != null) {
+                    throw new IllegalStateException("More than 1 desktop changes in one"
+                            + " transition? " + info);
+                }
+                desktopChange = change;
+                info.getChanges().remove(i);
+            }
+        }
         Transitions.TransitionFinishCallback finishCB = (wct) -> {
             --mInFlightSubAnimations;
             joinFinishArgs(wct);
             if (mInFlightSubAnimations > 0) return;
             finishCallback.onTransitionFinished(mFinishWCT);
         };
-        if (pipChange == null) {
+        if ((pipChange == null && desktopChange == null)
+                || (pipChange != null && desktopChange != null)) {
+            // Don't split the transition. Let the leftovers handler handle it all.
+            // TODO: b/? - split the transition into three pieces when there's both a PIP and a
+            //  desktop change are present. For example, during remote intent open over a desktop
+            //  with both a PIP capable task and an immersive task.
             if (mLeftoversHandler != null) {
                 mInFlightSubAnimations = 1;
                 if (mLeftoversHandler.startAnimation(
@@ -198,27 +228,52 @@
                 }
             }
             return false;
-        }
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Splitting PIP into a separate"
-                + " animation because remote-animation likely doesn't support it #%d",
-                info.getDebugId());
-        // Split the transition into 2 parts: the pip part and the rest.
-        mInFlightSubAnimations = 2;
-        // make a new startTransaction because pip's startEnterAnimation "consumes" it so
-        // we need a separate one to send over to launcher.
-        SurfaceControl.Transaction otherStartT = new SurfaceControl.Transaction();
+        } else if (pipChange != null && desktopChange == null) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Splitting PIP into a separate"
+                            + " animation because remote-animation likely doesn't support it #%d",
+                    info.getDebugId());
+            // Split the transition into 2 parts: the pip part and the rest.
+            mInFlightSubAnimations = 2;
+            // make a new startTransaction because pip's startEnterAnimation "consumes" it so
+            // we need a separate one to send over to launcher.
+            SurfaceControl.Transaction otherStartT = new SurfaceControl.Transaction();
 
-        mPipHandler.startEnterAnimation(pipChange, otherStartT, finishTransaction, finishCB);
+            mPipHandler.startEnterAnimation(pipChange, otherStartT, finishTransaction, finishCB);
 
-        // Dispatch the rest of the transition normally.
-        if (mLeftoversHandler != null
-                && mLeftoversHandler.startAnimation(mTransition, info,
-                startTransaction, finishTransaction, finishCB)) {
+            // Dispatch the rest of the transition normally.
+            if (mLeftoversHandler != null
+                    && mLeftoversHandler.startAnimation(mTransition, info,
+                    startTransaction, finishTransaction, finishCB)) {
+                return true;
+            }
+            mLeftoversHandler = mPlayer.dispatchTransition(
+                    mTransition, info, startTransaction, finishTransaction, finishCB,
+                    mMixedHandler);
             return true;
+        } else if (pipChange == null && desktopChange != null) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Splitting desktop change into a"
+                            + "separate animation because remote-animation likely doesn't support"
+                            + "it #%d", info.getDebugId());
+            mInFlightSubAnimations = 2;
+            SurfaceControl.Transaction otherStartT = new SurfaceControl.Transaction();
+
+            mDesktopTasksController.animateDesktopChange(
+                            mTransition, desktopChange, otherStartT, finishTransaction, finishCB);
+
+            // Dispatch the rest of the transition normally.
+            if (mLeftoversHandler != null
+                    && mLeftoversHandler.startAnimation(mTransition, info,
+                    startTransaction, finishTransaction, finishCB)) {
+                return true;
+            }
+            mLeftoversHandler = mPlayer.dispatchTransition(
+                    mTransition, info, startTransaction, finishTransaction, finishCB,
+                    mMixedHandler);
+            return true;
+        } else {
+            throw new IllegalStateException(
+                    "All PIP and Immersive combinations should've been handled");
         }
-        mLeftoversHandler = mPlayer.dispatchTransition(
-                mTransition, info, startTransaction, finishTransaction, finishCB, mMixedHandler);
-        return true;
     }
 
     private boolean animateUnfold(
@@ -246,6 +301,51 @@
                 mTransition, info, startTransaction, finishTransaction, finishCB);
     }
 
+    private boolean animateOpenInDesktop(
+            @NonNull IBinder transition,
+            @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "animateOpenInDesktop");
+        TransitionInfo.Change desktopChange = null;
+        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+            TransitionInfo.Change change = info.getChanges().get(i);
+            if (mDesktopTasksController.isDesktopChange(mTransition, change)) {
+                if (desktopChange != null) {
+                    throw new IllegalStateException("More than 1 desktop changes in one"
+                            + " transition? " + info);
+                }
+                desktopChange = change;
+                info.getChanges().remove(i);
+            }
+        }
+        final Transitions.TransitionFinishCallback finishCB = (wct) -> {
+            --mInFlightSubAnimations;
+            joinFinishArgs(wct);
+            if (mInFlightSubAnimations > 0) return;
+            finishCallback.onTransitionFinished(mFinishWCT);
+        };
+        if (desktopChange == null) {
+            if (mLeftoversHandler != null) {
+                mInFlightSubAnimations = 1;
+                if (mLeftoversHandler.startAnimation(
+                        mTransition, info, startTransaction, finishTransaction, finishCB)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Splitting desktop change into a"
+                + "separate animation #%d", info.getDebugId());
+        mInFlightSubAnimations = 2;
+        mDesktopTasksController.animateDesktopChange(
+                transition, desktopChange, startTransaction, finishTransaction, finishCB);
+        mLeftoversHandler = mPlayer.dispatchTransition(
+                mTransition, info, startTransaction, finishTransaction, finishCB, mMixedHandler);
+        return true;
+    }
+
     @Override
     void mergeAnimation(
             @NonNull IBinder transition, @NonNull TransitionInfo info,
@@ -279,7 +379,7 @@
             case TYPE_KEYGUARD:
                 mKeyguardHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
                 return;
-            case TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE:
+            case TYPE_OPTIONS_REMOTE_AND_PIP_OR_DESKTOP_CHANGE:
                 mPipHandler.end();
                 if (mLeftoversHandler != null) {
                     mLeftoversHandler.mergeAnimation(
@@ -289,6 +389,10 @@
             case TYPE_UNFOLD:
                 mUnfoldHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
                 return;
+            case TYPE_OPEN_IN_DESKTOP:
+                mDesktopTasksController.mergeAnimation(
+                        transition, info, t, mergeTarget, finishCallback);
+                return;
             default:
                 throw new IllegalStateException("Playing a default mixed transition with unknown or"
                         + " illegal type: " + mType);
@@ -310,12 +414,14 @@
             case TYPE_KEYGUARD:
                 mKeyguardHandler.onTransitionConsumed(transition, aborted, finishT);
                 break;
-            case TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE:
+            case TYPE_OPTIONS_REMOTE_AND_PIP_OR_DESKTOP_CHANGE:
                 mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
                 break;
             case TYPE_UNFOLD:
                 mUnfoldHandler.onTransitionConsumed(transition, aborted, finishT);
                 break;
+            case TYPE_OPEN_IN_DESKTOP:
+                mDesktopTasksController.onTransitionConsumed(transition, aborted, finishT);
             default:
                 break;
         }
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 346f21b..7c9cd08 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
@@ -18,6 +18,7 @@
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_FIRST_CUSTOM;
@@ -58,6 +59,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.provider.Settings;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -800,8 +802,17 @@
         track.mReadyTransitions.add(active);
 
         for (int i = 0; i < mObservers.size(); ++i) {
+            final boolean useTrace = Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER);
+            if (useTrace) {
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
+                        mObservers.get(i).getClass().getSimpleName() + "#onTransitionReady: "
+                                + transitTypeToString(info.getType()));
+            }
             mObservers.get(i).onTransitionReady(
                     active.mToken, info, active.mStartT, active.mFinishT);
+            if (useTrace) {
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+            }
         }
 
         /*
@@ -931,7 +942,7 @@
                 onFinish(ready.mToken, null);
                 return;
             }
-            playTransition(ready);
+            playTransitionWithTracing(ready);
             // Attempt to merge any more queued-up transitions.
             processReadyQueue(track);
             return;
@@ -1003,6 +1014,18 @@
         processReadyQueue(track);
     }
 
+    private void playTransitionWithTracing(@NonNull ActiveTransition active) {
+        final boolean useTrace = Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER);
+        if (useTrace) {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
+                    "playTransition: " + transitTypeToString(active.mInfo.getType()));
+        }
+        playTransition(active);
+        if (useTrace) {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+    }
+
     private void playTransition(@NonNull ActiveTransition active) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Playing animation for %s", active);
         final var token = active.mToken;
@@ -1022,6 +1045,12 @@
             if (consumed) {
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " animated by firstHandler");
                 mTransitionTracer.logDispatched(active.mInfo.getDebugId(), active.mHandler);
+                if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
+                    Trace.instant(TRACE_TAG_WINDOW_MANAGER,
+                            active.mHandler.getClass().getSimpleName()
+                                    + "#startAnimation animated "
+                                    + transitTypeToString(active.mInfo.getType()));
+                }
                 return;
             }
         }
@@ -1052,6 +1081,12 @@
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " animated by %s",
                         mHandlers.get(i));
                 mTransitionTracer.logDispatched(info.getDebugId(), mHandlers.get(i));
+                if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
+                    Trace.instant(TRACE_TAG_WINDOW_MANAGER,
+                            mHandlers.get(i).getClass().getSimpleName()
+                                    + "#startAnimation animated "
+                                    + transitTypeToString(info.getType()));
+                }
                 return mHandlers.get(i);
             }
         }
@@ -1059,6 +1094,26 @@
                 "This shouldn't happen, maybe the default handler is broken.");
     }
 
+    private Pair<TransitionHandler, WindowContainerTransaction> dispatchRequestWithTracing(
+            @NonNull IBinder transition, @NonNull TransitionRequestInfo request,
+            @Nullable TransitionHandler skip) {
+        final boolean useTrace = Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER);
+        if (useTrace) {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
+                    "dispatchRequest: " + transitTypeToString(request.getType()));
+        }
+        Pair<TransitionHandler, WindowContainerTransaction> result =
+                dispatchRequest(transition, request, skip);
+        if (useTrace) {
+            if (result != null) {
+                Trace.instant(TRACE_TAG_WINDOW_MANAGER, result.first.getClass().getSimpleName()
+                        + "#handleRequest handled " + transitTypeToString(request.getType()));
+            }
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+        return result;
+    }
+
     /**
      * Gives every handler (in order) a chance to handle request until one consumes the transition.
      * @return the WindowContainerTransaction given by the handler which consumed the transition.
@@ -1197,12 +1252,11 @@
             mSleepHandler.handleRequest(transitionToken, request);
             active.mHandler = mSleepHandler;
         } else {
-            for (int i = mHandlers.size() - 1; i >= 0; --i) {
-                wct = mHandlers.get(i).handleRequest(transitionToken, request);
-                if (wct != null) {
-                    active.mHandler = mHandlers.get(i);
-                    break;
-                }
+            Pair<TransitionHandler, WindowContainerTransaction> requestResult =
+                    dispatchRequestWithTracing(transitionToken, request, /* skip= */ null);
+            if (requestResult != null) {
+                active.mHandler = requestResult.first;
+                wct = requestResult.second;
             }
             if (request.getDisplayChange() != null) {
                 TransitionRequestInfo.DisplayChange change = request.getDisplayChange();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
index 60c9222..78e7962 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
@@ -29,8 +29,6 @@
 import android.view.SurfaceControl;
 import android.window.DesktopModeFlags;
 
-import androidx.annotation.NonNull;
-
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -129,13 +127,15 @@
 
         // If width or height are negative or exceeding the width or height constraints, revert the
         // respective bounds to use previous bound dimensions.
-        if (isExceedingWidthConstraint(repositionTaskBounds, stableBounds, displayController,
+        if (isExceedingWidthConstraint(repositionTaskBounds.width(),
+                /* startingWidth= */ oldRight - oldLeft, stableBounds, displayController,
                 windowDecoration)) {
             repositionTaskBounds.right = oldRight;
             repositionTaskBounds.left = oldLeft;
             isAspectRatioMaintained = false;
         }
-        if (isExceedingHeightConstraint(repositionTaskBounds, stableBounds, displayController,
+        if (isExceedingHeightConstraint(repositionTaskBounds.height(),
+                /* startingHeight= */oldBottom - oldTop, stableBounds, displayController,
                 windowDecoration)) {
             repositionTaskBounds.top = oldTop;
             repositionTaskBounds.bottom = oldBottom;
@@ -208,28 +208,34 @@
         return result;
     }
 
-    private static boolean isExceedingWidthConstraint(@NonNull Rect repositionTaskBounds,
+    private static boolean isExceedingWidthConstraint(int repositionedWidth, int startingWidth,
             Rect maxResizeBounds, DisplayController displayController,
             WindowDecoration windowDecoration) {
+        boolean isSizeIncreasing = (repositionedWidth - startingWidth) > 0;
         // Check if width is less than the minimum width constraint.
-        if (repositionTaskBounds.width() < getMinWidth(displayController, windowDecoration)) {
-            return true;
+        if (repositionedWidth < getMinWidth(displayController, windowDecoration)) {
+            // Only allow width to be increased if it is already below minimum.
+            return !isSizeIncreasing;
         }
         // Check if width is more than the maximum resize bounds on desktop windowing mode.
+        // Only allow width to be decreased if it already exceeds maximum.
         return isSizeConstraintForDesktopModeEnabled(windowDecoration.mDecorWindowContext)
-                && repositionTaskBounds.width() > maxResizeBounds.width();
+                && repositionedWidth > maxResizeBounds.width() && isSizeIncreasing;
     }
 
-    private static boolean isExceedingHeightConstraint(@NonNull Rect repositionTaskBounds,
+    private static boolean isExceedingHeightConstraint(int repositionedHeight, int startingHeight,
             Rect maxResizeBounds, DisplayController displayController,
             WindowDecoration windowDecoration) {
+        boolean isSizeIncreasing = (repositionedHeight - startingHeight) > 0;
         // Check if height is less than the minimum height constraint.
-        if (repositionTaskBounds.height() < getMinHeight(displayController, windowDecoration)) {
-            return true;
+        if (repositionedHeight < getMinHeight(displayController, windowDecoration)) {
+            // Only allow height to be increased if it is already below minimum.
+            return !isSizeIncreasing;
         }
         // Check if height is more than the maximum resize bounds on desktop windowing mode.
+        // Only allow height to be decreased if it already exceeds maximum.
         return isSizeConstraintForDesktopModeEnabled(windowDecoration.mDecorWindowContext)
-                && repositionTaskBounds.height() > maxResizeBounds.height();
+                && repositionedHeight > maxResizeBounds.height() && isSizeIncreasing;
     }
 
     private static float getMinWidth(DisplayController displayController,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIStatusManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIStatusManagerTest.java
index d6059a8..8fd7c0e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIStatusManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIStatusManagerTest.java
@@ -16,6 +16,10 @@
 
 package com.android.wm.shell.compatui;
 
+import static com.android.wm.shell.compatui.CompatUIStatusManager.COMPAT_UI_EDUCATION_HIDDEN;
+
+import static junit.framework.Assert.assertEquals;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -25,7 +29,6 @@
 
 import com.android.wm.shell.ShellTestCase;
 
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -63,13 +66,75 @@
         assertFalse(mStatusManager.isEducationVisible());
     }
 
+    @Test
+    public void valuesAreCached() {
+        // At the beginning the value is not read or written because
+        // we access the reader in lazy way.
+        mTestState.assertReaderInvocations(0);
+        mTestState.assertWriterInvocations(0);
+
+        // We read the value when we start. Initial value is hidden.
+        assertFalse(mStatusManager.isEducationVisible());
+        mTestState.assertReaderInvocations(1);
+        mTestState.assertWriterInvocations(0);
+
+        // We send the event for the same state which is not written.
+        mStatusManager.onEducationHidden();
+        assertFalse(mStatusManager.isEducationVisible());
+        mTestState.assertReaderInvocations(1);
+        mTestState.assertWriterInvocations(0);
+
+        // We send the event for the different state which is written but
+        // not read again.
+        mStatusManager.onEducationShown();
+        assertTrue(mStatusManager.isEducationVisible());
+        mTestState.assertReaderInvocations(1);
+        mTestState.assertWriterInvocations(1);
+
+        // We read multiple times and we don't read the value again
+        mStatusManager.isEducationVisible();
+        mStatusManager.isEducationVisible();
+        mStatusManager.isEducationVisible();
+        mTestState.assertReaderInvocations(1);
+        mTestState.assertWriterInvocations(1);
+
+        // We write different values. Writer  is only accessed when
+        // the value changes.
+        mStatusManager.onEducationHidden(); // change
+        mStatusManager.onEducationHidden();
+        mStatusManager.onEducationShown(); // change
+        mStatusManager.onEducationShown();
+        mStatusManager.onEducationHidden(); // change
+        mStatusManager.onEducationShown(); // change
+        mTestState.assertReaderInvocations(1);
+        mTestState.assertWriterInvocations(5);
+    }
+
     static class FakeCompatUIStatusManagerTest {
 
-        int mCurrentStatus = 0;
+        int mCurrentStatus = COMPAT_UI_EDUCATION_HIDDEN;
 
-        final IntSupplier mReader = () -> mCurrentStatus;
+        int mReaderInvocations;
 
-        final IntConsumer mWriter = newStatus -> mCurrentStatus = newStatus;
+        int mWriterInvocations;
+
+        final IntSupplier mReader = () -> {
+            mReaderInvocations++;
+            return mCurrentStatus;
+        };
+
+        final IntConsumer mWriter = newStatus -> {
+            mWriterInvocations++;
+            mCurrentStatus = newStatus;
+        };
+
+        void assertWriterInvocations(int expected) {
+            assertEquals(expected, mWriterInvocations);
+        }
+
+        void assertReaderInvocations(int expected) {
+            assertEquals(expected, mReaderInvocations);
+        }
 
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
similarity index 69%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandlerTest.kt
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
index ef99b00..e83f5c7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
@@ -15,6 +15,7 @@
  */
 package com.android.wm.shell.desktopmode
 
+import android.app.ActivityManager.RunningTaskInfo
 import android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS
 import android.graphics.Rect
 import android.os.Binder
@@ -58,13 +59,13 @@
 import org.mockito.kotlin.whenever
 
 /**
- * Tests for [DesktopFullImmersiveTransitionHandler].
+ * Tests for [DesktopImmersiveController].
  *
- * Usage: atest WMShellUnitTests:DesktopFullImmersiveTransitionHandlerTest
+ * Usage: atest WMShellUnitTests:DesktopImmersiveControllerTest
  */
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
-class DesktopFullImmersiveTransitionHandlerTest : ShellTestCase() {
+class DesktopImmersiveControllerTest : ShellTestCase() {
 
     @JvmField @Rule val setFlagsRule = SetFlagsRule()
 
@@ -75,7 +76,7 @@
     @Mock private lateinit var mockDisplayLayout: DisplayLayout
     private val transactionSupplier = { SurfaceControl.Transaction() }
 
-    private lateinit var immersiveHandler: DesktopFullImmersiveTransitionHandler
+    private lateinit var controller: DesktopImmersiveController
 
     @Before
     fun setUp() {
@@ -87,7 +88,7 @@
         whenever(mockDisplayLayout.getStableBounds(any())).thenAnswer { invocation ->
             (invocation.getArgument(0) as Rect).set(STABLE_BOUNDS)
         }
-        immersiveHandler = DesktopFullImmersiveTransitionHandler(
+        controller = DesktopImmersiveController(
             transitions = mockTransitions,
             desktopRepository = desktopRepository,
             displayController = mockDisplayController,
@@ -100,7 +101,7 @@
     fun enterImmersive_transitionReady_updatesRepository() {
         val task = createFreeformTask()
         val mockBinder = mock(IBinder::class.java)
-        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(immersiveHandler)))
+        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(controller)))
             .thenReturn(mockBinder)
         desktopRepository.setTaskInFullImmersiveState(
             displayId = task.displayId,
@@ -108,16 +109,14 @@
             immersive = false
         )
 
-        immersiveHandler.moveTaskToImmersive(task)
-        immersiveHandler.onTransitionReady(
+        controller.moveTaskToImmersive(task)
+        controller.onTransitionReady(
             transition = mockBinder,
             info = createTransitionInfo(
-                changes = listOf(
-                    TransitionInfo.Change(task.token, SurfaceControl()).apply {
-                        taskInfo = task
-                    }
-                )
-            )
+                changes = listOf(createChange(task))
+            ),
+            startTransaction = SurfaceControl.Transaction(),
+            finishTransaction = SurfaceControl.Transaction(),
         )
 
         assertThat(desktopRepository.isTaskInFullImmersiveState(task.taskId)).isTrue()
@@ -128,7 +127,7 @@
     fun enterImmersive_savesPreImmersiveBounds() {
         val task = createFreeformTask()
         val mockBinder = mock(IBinder::class.java)
-        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(immersiveHandler)))
+        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(controller)))
             .thenReturn(mockBinder)
         desktopRepository.setTaskInFullImmersiveState(
             displayId = task.displayId,
@@ -137,16 +136,14 @@
         )
         assertThat(desktopRepository.removeBoundsBeforeFullImmersive(task.taskId)).isNull()
 
-        immersiveHandler.moveTaskToImmersive(task)
-        immersiveHandler.onTransitionReady(
+        controller.moveTaskToImmersive(task)
+        controller.onTransitionReady(
             transition = mockBinder,
             info = createTransitionInfo(
-                changes = listOf(
-                    TransitionInfo.Change(task.token, SurfaceControl()).apply {
-                        taskInfo = task
-                    }
-                )
-            )
+                changes = listOf(createChange(task))
+            ),
+            startTransaction = SurfaceControl.Transaction(),
+            finishTransaction = SurfaceControl.Transaction(),
         )
 
         assertThat(desktopRepository.removeBoundsBeforeFullImmersive(task.taskId)).isNotNull()
@@ -156,7 +153,7 @@
     fun exitImmersive_transitionReady_updatesRepository() {
         val task = createFreeformTask()
         val mockBinder = mock(IBinder::class.java)
-        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(immersiveHandler)))
+        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(controller)))
             .thenReturn(mockBinder)
         desktopRepository.setTaskInFullImmersiveState(
             displayId = task.displayId,
@@ -164,16 +161,14 @@
             immersive = true
         )
 
-        immersiveHandler.moveTaskToNonImmersive(task)
-        immersiveHandler.onTransitionReady(
+        controller.moveTaskToNonImmersive(task)
+        controller.onTransitionReady(
             transition = mockBinder,
             info = createTransitionInfo(
-                changes = listOf(
-                    TransitionInfo.Change(task.token, SurfaceControl()).apply {
-                        taskInfo = task
-                    }
-                )
-            )
+                changes = listOf(createChange(task))
+            ),
+            startTransaction = SurfaceControl.Transaction(),
+            finishTransaction = SurfaceControl.Transaction(),
         )
 
         assertThat(desktopRepository.isTaskInFullImmersiveState(task.taskId)).isFalse()
@@ -184,7 +179,7 @@
     fun exitImmersive_onTransitionReady_removesBoundsBeforeImmersive() {
         val task = createFreeformTask()
         val mockBinder = mock(IBinder::class.java)
-        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(immersiveHandler)))
+        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(controller)))
             .thenReturn(mockBinder)
         desktopRepository.setTaskInFullImmersiveState(
             displayId = task.displayId,
@@ -193,16 +188,14 @@
         )
         desktopRepository.saveBoundsBeforeFullImmersive(task.taskId, Rect(100, 100, 600, 600))
 
-        immersiveHandler.moveTaskToNonImmersive(task)
-        immersiveHandler.onTransitionReady(
+        controller.moveTaskToNonImmersive(task)
+        controller.onTransitionReady(
             transition = mockBinder,
             info = createTransitionInfo(
-                changes = listOf(
-                    TransitionInfo.Change(task.token, SurfaceControl()).apply {
-                        taskInfo = task
-                    }
-                )
-            )
+                changes = listOf(createChange(task))
+            ),
+            startTransaction = SurfaceControl.Transaction(),
+            finishTransaction = SurfaceControl.Transaction(),
         )
 
         assertThat(desktopRepository.removeBoundsBeforeMaximize(task.taskId)).isNull()
@@ -217,16 +210,15 @@
             immersive = true
         )
 
-        immersiveHandler.onTransitionReady(
+        controller.onTransitionReady(
             transition = mock(IBinder::class.java),
             info = createTransitionInfo(
-                changes = listOf(
-                    TransitionInfo.Change(task.token, SurfaceControl()).apply {
-                        taskInfo = task
-                        setRotation(/* start= */ Surface.ROTATION_0, /* end= */ Surface.ROTATION_90)
-                    }
-                )
-            )
+                changes = listOf(createChange(task).apply {
+                    setRotation(/* start= */ Surface.ROTATION_0, /* end= */ Surface.ROTATION_90)
+                })
+            ),
+            startTransaction = SurfaceControl.Transaction(),
+            finishTransaction = SurfaceControl.Transaction(),
         )
 
         assertThat(desktopRepository.isTaskInFullImmersiveState(task.taskId)).isFalse()
@@ -236,28 +228,28 @@
     fun enterImmersive_inProgress_ignores() {
         val task = createFreeformTask()
         val mockBinder = mock(IBinder::class.java)
-        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(immersiveHandler)))
+        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(controller)))
             .thenReturn(mockBinder)
 
-        immersiveHandler.moveTaskToImmersive(task)
-        immersiveHandler.moveTaskToImmersive(task)
+        controller.moveTaskToImmersive(task)
+        controller.moveTaskToImmersive(task)
 
         verify(mockTransitions, times(1))
-            .startTransition(eq(TRANSIT_CHANGE), any(), eq(immersiveHandler))
+            .startTransition(eq(TRANSIT_CHANGE), any(), eq(controller))
     }
 
     @Test
     fun exitImmersive_inProgress_ignores() {
         val task = createFreeformTask()
         val mockBinder = mock(IBinder::class.java)
-        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(immersiveHandler)))
+        whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(controller)))
             .thenReturn(mockBinder)
 
-        immersiveHandler.moveTaskToNonImmersive(task)
-        immersiveHandler.moveTaskToNonImmersive(task)
+        controller.moveTaskToNonImmersive(task)
+        controller.moveTaskToNonImmersive(task)
 
         verify(mockTransitions, times(1))
-            .startTransition(eq(TRANSIT_CHANGE), any(), eq(immersiveHandler))
+            .startTransition(eq(TRANSIT_CHANGE), any(), eq(controller))
     }
 
     @Test
@@ -273,9 +265,9 @@
             immersive = true
         )
 
-        immersiveHandler.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
 
-        assertThat(immersiveHandler.pendingExternalExitTransitions.any { exit ->
+        assertThat(controller.pendingExternalExitTransitions.any { exit ->
             exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
                     && exit.taskId == task.taskId
         }).isTrue()
@@ -294,9 +286,9 @@
             immersive = false
         )
 
-        immersiveHandler.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
 
-        assertThat(immersiveHandler.pendingExternalExitTransitions.any { exit ->
+        assertThat(controller.pendingExternalExitTransitions.any { exit ->
             exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
                     && exit.taskId == task.taskId
         }).isFalse()
@@ -315,7 +307,7 @@
             immersive = true
         )
 
-        immersiveHandler.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
 
         assertThat(wct.hasBoundsChange(task.token)).isTrue()
     }
@@ -333,13 +325,38 @@
             immersive = false
         )
 
-        immersiveHandler.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
 
         assertThat(wct.hasBoundsChange(task.token)).isFalse()
     }
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+    fun exitImmersiveIfApplicable_byDisplay_withExcludeTask_doesNotExit() {
+        val task = createFreeformTask()
+        whenever(mockShellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
+        val wct = WindowContainerTransaction()
+        val transition = Binder()
+        desktopRepository.setTaskInFullImmersiveState(
+            displayId = DEFAULT_DISPLAY,
+            taskId = task.taskId,
+            immersive = true
+        )
+
+        controller.exitImmersiveIfApplicable(
+            wct = wct,
+            displayId = DEFAULT_DISPLAY,
+            excludeTaskId = task.taskId
+        )?.invoke(transition)
+
+        assertThat(controller.pendingExternalExitTransitions.any { exit ->
+            exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
+                    && exit.taskId == task.taskId
+        }).isFalse()
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
     fun exitImmersiveIfApplicable_byTask_inImmersive_changesTaskBounds() {
         val task = createFreeformTask()
         whenever(mockShellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
@@ -350,7 +367,7 @@
             immersive = true
         )
 
-        immersiveHandler.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
 
         assertThat(wct.hasBoundsChange(task.token)).isTrue()
     }
@@ -367,7 +384,7 @@
             immersive = false
         )
 
-        immersiveHandler.exitImmersiveIfApplicable(wct, task)
+        controller.exitImmersiveIfApplicable(wct, task)
 
         assertThat(wct.hasBoundsChange(task.token)).isFalse()
     }
@@ -385,9 +402,9 @@
             immersive = true
         )
 
-        immersiveHandler.exitImmersiveIfApplicable(wct, task)?.invoke(transition)
+        controller.exitImmersiveIfApplicable(wct, task)?.invoke(transition)
 
-        assertThat(immersiveHandler.pendingExternalExitTransitions.any { exit ->
+        assertThat(controller.pendingExternalExitTransitions.any { exit ->
             exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
                     && exit.taskId == task.taskId
         }).isTrue()
@@ -406,9 +423,9 @@
             immersive = false
         )
 
-        immersiveHandler.exitImmersiveIfApplicable(wct, task)?.invoke(transition)
+        controller.exitImmersiveIfApplicable(wct, task)?.invoke(transition)
 
-        assertThat(immersiveHandler.pendingExternalExitTransitions.any { exit ->
+        assertThat(controller.pendingExternalExitTransitions.any { exit ->
             exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
                     && exit.taskId == task.taskId
         }).isFalse()
@@ -416,7 +433,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
-    fun onTransitionReady_pendingExit_removesPendingExit() {
+    fun onTransitionReady_pendingExit_removesPendingExitOnFinish() {
         val task = createFreeformTask()
         whenever(mockShellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
         val wct = WindowContainerTransaction()
@@ -426,18 +443,19 @@
             taskId = task.taskId,
             immersive = true
         )
-        immersiveHandler.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
 
-        immersiveHandler.onTransitionReady(
+        controller.onTransitionReady(
             transition = transition,
             info = createTransitionInfo(
-                changes = listOf(
-                    TransitionInfo.Change(task.token, SurfaceControl()).apply { taskInfo = task }
-                )
-            )
+                changes = listOf(createChange(task))
+            ),
+            startTransaction = SurfaceControl.Transaction(),
+            finishTransaction = SurfaceControl.Transaction(),
         )
+        controller.onTransitionFinished(transition, aborted = false)
 
-        assertThat(immersiveHandler.pendingExternalExitTransitions.any { exit ->
+        assertThat(controller.pendingExternalExitTransitions.any { exit ->
             exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
                     && exit.taskId == task.taskId
         }).isFalse()
@@ -445,6 +463,42 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+    fun onTransitionReady_pendingExit_withMerge_removesPendingExitOnFinish() {
+        val task = createFreeformTask()
+        whenever(mockShellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
+        val wct = WindowContainerTransaction()
+        val transition = Binder()
+        val mergedToTransition = Binder()
+        desktopRepository.setTaskInFullImmersiveState(
+            displayId = DEFAULT_DISPLAY,
+            taskId = task.taskId,
+            immersive = true
+        )
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+
+        controller.onTransitionReady(
+            transition = transition,
+            info = createTransitionInfo(
+                changes = listOf(createChange(task))
+            ),
+            startTransaction = SurfaceControl.Transaction(),
+            finishTransaction = SurfaceControl.Transaction(),
+        )
+        controller.onTransitionMerged(transition, mergedToTransition)
+        controller.onTransitionFinished(mergedToTransition, aborted = false)
+
+        assertThat(controller.pendingExternalExitTransitions.any { exit ->
+            exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
+                    && exit.taskId == task.taskId
+        }).isFalse()
+        assertThat(controller.pendingExternalExitTransitions.any { exit ->
+            exit.transition == mergedToTransition && exit.displayId == DEFAULT_DISPLAY
+                    && exit.taskId == task.taskId
+        }).isFalse()
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
     fun onTransitionReady_pendingExit_updatesRepository() {
         val task = createFreeformTask()
         whenever(mockShellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
@@ -455,15 +509,15 @@
             taskId = task.taskId,
             immersive = true
         )
-        immersiveHandler.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
 
-        immersiveHandler.onTransitionReady(
+        controller.onTransitionReady(
             transition = transition,
             info = createTransitionInfo(
-                changes = listOf(
-                    TransitionInfo.Change(task.token, SurfaceControl()).apply { taskInfo = task }
-                )
-            )
+                changes = listOf(createChange(task))
+            ),
+            startTransaction = SurfaceControl.Transaction(),
+            finishTransaction = SurfaceControl.Transaction(),
         )
 
         assertThat(desktopRepository.isTaskInFullImmersiveState(task.taskId)).isFalse()
@@ -485,15 +539,15 @@
             immersive = true
         )
         desktopRepository.saveBoundsBeforeFullImmersive(task.taskId, Rect(100, 100, 600, 600))
-        immersiveHandler.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
 
-        immersiveHandler.onTransitionReady(
+        controller.onTransitionReady(
             transition = transition,
             info = createTransitionInfo(
-                changes = listOf(
-                    TransitionInfo.Change(task.token, SurfaceControl()).apply { taskInfo = task }
-                )
-            )
+                changes = listOf(createChange(task))
+            ),
+            startTransaction = SurfaceControl.Transaction(),
+            finishTransaction = SurfaceControl.Transaction(),
         )
 
         assertThat(desktopRepository.removeBoundsBeforeMaximize(task.taskId)).isNull()
@@ -512,7 +566,7 @@
             immersive = true
         )
 
-        immersiveHandler.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
 
         assertThat(
             wct.hasBoundsChange(task.token, calculateMaximizeBounds(mockDisplayLayout, task))
@@ -536,7 +590,7 @@
         val preImmersiveBounds = Rect(100, 100, 500, 500)
         desktopRepository.saveBoundsBeforeFullImmersive(task.taskId, preImmersiveBounds)
 
-        immersiveHandler.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
 
         assertThat(
             wct.hasBoundsChange(task.token, preImmersiveBounds)
@@ -559,7 +613,7 @@
             immersive = true
         )
 
-        immersiveHandler.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+        controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
 
         assertThat(
             wct.hasBoundsChange(task.token, calculateInitialBounds(mockDisplayLayout, task))
@@ -577,13 +631,32 @@
             taskId = task.taskId,
             immersive = true
         )
-        immersiveHandler.exitImmersiveIfApplicable(wct, task)?.invoke(Binder())
+        controller.exitImmersiveIfApplicable(wct, task)?.invoke(Binder())
 
-        immersiveHandler.moveTaskToNonImmersive(task)
+        controller.moveTaskToNonImmersive(task)
 
         verify(mockTransitions, never()).startTransition(any(), any(), any())
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+    fun exitImmersiveIfApplicable_inImmersive_isImmersiveChange() {
+        val task = createFreeformTask()
+        whenever(mockShellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
+        val wct = WindowContainerTransaction()
+        val transition = Binder()
+        val change = createChange(task)
+        desktopRepository.setTaskInFullImmersiveState(
+            displayId = DEFAULT_DISPLAY,
+            taskId = task.taskId,
+            immersive = true
+        )
+
+        controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+
+        assertThat(controller.isImmersiveChange(transition, change)).isTrue()
+    }
+
     private fun createTransitionInfo(
         @TransitionType type: Int = TRANSIT_CHANGE,
         @TransitionFlags flags: Int = 0,
@@ -592,6 +665,11 @@
         changes.forEach { change -> addChange(change) }
     }
 
+    private fun createChange(task: RunningTaskInfo): TransitionInfo.Change =
+        TransitionInfo.Change(task.token, SurfaceControl()).apply {
+            taskInfo = task
+        }
+
     private fun WindowContainerTransaction.hasBoundsChange(token: WindowContainerToken): Boolean =
         this.changes.any { change ->
             change.key == token.asBinder()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
index 81d59d5..5036837 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
@@ -147,7 +147,7 @@
     fun startAnimation_withClosingDesktopTask_callsCloseTaskHandler() {
         val transition = mock<IBinder>()
         val transitionInfo = createTransitionInfo(task = createTask(WINDOWING_MODE_FREEFORM))
-        whenever(desktopRepository.getActiveNonMinimizedTaskCount(any())).thenReturn(2)
+        whenever(desktopRepository.getExpandedTaskCount(any())).thenReturn(2)
         whenever(
                 closeDesktopTaskTransitionHandler.startAnimation(any(), any(), any(), any(), any())
             )
@@ -170,7 +170,7 @@
     fun startAnimation_withClosingLastDesktopTask_dispatchesTransition() {
         val transition = mock<IBinder>()
         val transitionInfo = createTransitionInfo(task = createTask(WINDOWING_MODE_FREEFORM))
-        whenever(desktopRepository.getActiveNonMinimizedTaskCount(any())).thenReturn(1)
+        whenever(desktopRepository.getExpandedTaskCount(any())).thenReturn(1)
         whenever(transitions.dispatchTransition(any(), any(), any(), any(), any(), any()))
             .thenReturn(mock())
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
index 3e22803..d90443c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
@@ -898,7 +898,7 @@
     }
 
     @Test
-    fun getActiveNonMinimizedOrderedTasks_returnsFreeformTasksInCorrectOrder() {
+    fun getExpandedTasksOrdered_returnsFreeformTasksInCorrectOrder() {
         repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 1)
         repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 2)
         repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 3)
@@ -907,13 +907,13 @@
         repo.addOrMoveFreeformTaskToTop(displayId = 0, taskId = 2)
         repo.addOrMoveFreeformTaskToTop(displayId = 0, taskId = 1)
 
-        val tasks = repo.getActiveNonMinimizedOrderedTasks(displayId = 0)
+        val tasks = repo.getExpandedTasksOrdered(displayId = 0)
 
         assertThat(tasks).containsExactly(1, 2, 3).inOrder()
     }
 
     @Test
-    fun getActiveNonMinimizedOrderedTasks_excludesMinimizedTasks() {
+    fun getExpandedTasksOrdered_excludesMinimizedTasks() {
         repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 1)
         repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 2)
         repo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 3)
@@ -923,7 +923,7 @@
         repo.addOrMoveFreeformTaskToTop(displayId = DEFAULT_DISPLAY, taskId = 1)
         repo.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = 2)
 
-        val tasks = repo.getActiveNonMinimizedOrderedTasks(displayId = DEFAULT_DISPLAY)
+        val tasks = repo.getExpandedTasksOrdered(displayId = DEFAULT_DISPLAY)
 
         assertThat(tasks).containsExactly(1, 3).inOrder()
     }
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 7c336cd..bc2b36c 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
@@ -201,7 +201,7 @@
   lateinit var toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler
   @Mock lateinit var dragToDesktopTransitionHandler: DragToDesktopTransitionHandler
   @Mock
-  lateinit var mockDesktopFullImmersiveTransitionHandler: DesktopFullImmersiveTransitionHandler
+  lateinit var mMockDesktopImmersiveController: DesktopImmersiveController
   @Mock lateinit var launchAdjacentController: LaunchAdjacentController
   @Mock lateinit var splitScreenController: SplitScreenController
   @Mock lateinit var recentsTransitionHandler: RecentsTransitionHandler
@@ -322,7 +322,7 @@
         dragAndDropTransitionHandler,
         toggleResizeDesktopTaskTransitionHandler,
         dragToDesktopTransitionHandler,
-        mockDesktopFullImmersiveTransitionHandler,
+        mMockDesktopImmersiveController,
         taskRepository,
         desktopModeLoggerTransitionObserver,
         launchAdjacentController,
@@ -1773,7 +1773,7 @@
 
     controller.minimizeTask(task)
 
-    verify(mockDesktopFullImmersiveTransitionHandler).exitImmersiveIfApplicable(any(), eq(task))
+    verify(mMockDesktopImmersiveController).exitImmersiveIfApplicable(any(), eq(task))
   }
 
   @Test
@@ -1783,7 +1783,7 @@
     val runOnTransit = RunOnStartTransitionCallback()
     whenever(freeformTaskTransitionStarter.startMinimizedModeTransition(any()))
       .thenReturn(transition)
-    whenever(mockDesktopFullImmersiveTransitionHandler.exitImmersiveIfApplicable(any(), eq(task)))
+    whenever(mMockDesktopImmersiveController.exitImmersiveIfApplicable(any(), eq(task)))
       .thenReturn(runOnTransit)
 
     controller.minimizeTask(task)
@@ -3092,13 +3092,14 @@
     val transition = Binder()
     whenever(transitions.startTransition(eq(TRANSIT_OPEN), any(), anyOrNull()))
       .thenReturn(transition)
-    whenever(mockDesktopFullImmersiveTransitionHandler
-      .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId))).thenReturn(runOnStartTransit)
+    whenever(mMockDesktopImmersiveController
+      .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId)))
+      .thenReturn(runOnStartTransit)
 
     runOpenInstance(immersiveTask, freeformTask.taskId)
 
-    verify(mockDesktopFullImmersiveTransitionHandler)
-      .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId))
+    verify(mMockDesktopImmersiveController)
+      .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId))
     runOnStartTransit.assertOnlyInvocation(transition)
   }
 
@@ -3445,7 +3446,7 @@
 
     controller.toggleDesktopTaskFullImmersiveState(task)
 
-    verify(mockDesktopFullImmersiveTransitionHandler).moveTaskToImmersive(task)
+    verify(mMockDesktopImmersiveController).moveTaskToImmersive(task)
   }
 
   @Test
@@ -3455,7 +3456,7 @@
 
     controller.toggleDesktopTaskFullImmersiveState(task)
 
-    verify(mockDesktopFullImmersiveTransitionHandler).moveTaskToNonImmersive(task)
+    verify(mMockDesktopImmersiveController).moveTaskToNonImmersive(task)
   }
 
   @Test
@@ -3467,7 +3468,7 @@
     task.requestedVisibleTypes = WindowInsets.Type.statusBars()
     controller.onTaskInfoChanged(task)
 
-    verify(mockDesktopFullImmersiveTransitionHandler).moveTaskToNonImmersive(task)
+    verify(mMockDesktopImmersiveController).moveTaskToNonImmersive(task)
   }
 
   @Test
@@ -3479,7 +3480,7 @@
     task.requestedVisibleTypes = WindowInsets.Type.statusBars()
     controller.onTaskInfoChanged(task)
 
-    verify(mockDesktopFullImmersiveTransitionHandler, never()).moveTaskToNonImmersive(task)
+    verify(mMockDesktopImmersiveController, never()).moveTaskToNonImmersive(task)
   }
 
   @Test
@@ -3488,13 +3489,14 @@
     val wct = WindowContainerTransaction()
     val runOnStartTransit = RunOnStartTransitionCallback()
     val transition = Binder()
-    whenever(mockDesktopFullImmersiveTransitionHandler
-      .exitImmersiveIfApplicable(wct, task.displayId)).thenReturn(runOnStartTransit)
+    whenever(mMockDesktopImmersiveController
+      .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)).thenReturn(runOnStartTransit)
     whenever(enterDesktopTransitionHandler.moveToDesktop(wct, UNKNOWN)).thenReturn(transition)
 
     controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN)
 
-    verify(mockDesktopFullImmersiveTransitionHandler).exitImmersiveIfApplicable(wct, task.displayId)
+    verify(mMockDesktopImmersiveController)
+      .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)
     runOnStartTransit.assertOnlyInvocation(transition)
   }
 
@@ -3504,13 +3506,14 @@
     val wct = WindowContainerTransaction()
     val runOnStartTransit = RunOnStartTransitionCallback()
     val transition = Binder()
-    whenever(mockDesktopFullImmersiveTransitionHandler
-      .exitImmersiveIfApplicable(wct, task.displayId)).thenReturn(runOnStartTransit)
+    whenever(mMockDesktopImmersiveController
+      .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)).thenReturn(runOnStartTransit)
     whenever(enterDesktopTransitionHandler.moveToDesktop(wct, UNKNOWN)).thenReturn(transition)
 
     controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN)
 
-    verify(mockDesktopFullImmersiveTransitionHandler).exitImmersiveIfApplicable(wct, task.displayId)
+    verify(mMockDesktopImmersiveController)
+      .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)
     runOnStartTransit.assertOnlyInvocation(transition)
   }
 
@@ -3519,14 +3522,15 @@
     val task = setUpFreeformTask(background = true)
     val runOnStartTransit = RunOnStartTransitionCallback()
     val transition = Binder()
-    whenever(mockDesktopFullImmersiveTransitionHandler
-      .exitImmersiveIfApplicable(any(), eq(task.displayId))).thenReturn(runOnStartTransit)
+    whenever(mMockDesktopImmersiveController
+      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)))
+      .thenReturn(runOnStartTransit)
     whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition)
 
     controller.moveTaskToFront(task.taskId, remoteTransition = null)
 
-    verify(mockDesktopFullImmersiveTransitionHandler)
-      .exitImmersiveIfApplicable(any(), eq(task.displayId))
+    verify(mMockDesktopImmersiveController)
+      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))
     runOnStartTransit.assertOnlyInvocation(transition)
   }
 
@@ -3535,14 +3539,15 @@
     val task = setUpFreeformTask(background = false)
     val runOnStartTransit = RunOnStartTransitionCallback()
     val transition = Binder()
-    whenever(mockDesktopFullImmersiveTransitionHandler
-      .exitImmersiveIfApplicable(any(), eq(task.displayId))).thenReturn(runOnStartTransit)
+    whenever(mMockDesktopImmersiveController
+      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)))
+      .thenReturn(runOnStartTransit)
     whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition)
 
     controller.moveTaskToFront(task.taskId, remoteTransition = null)
 
-    verify(mockDesktopFullImmersiveTransitionHandler)
-      .exitImmersiveIfApplicable(any(), eq(task.displayId))
+    verify(mMockDesktopImmersiveController)
+      .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))
     runOnStartTransit.assertOnlyInvocation(transition)
   }
 
@@ -3555,7 +3560,7 @@
 
     controller.handleRequest(binder, createTransition(task))
 
-    verify(mockDesktopFullImmersiveTransitionHandler)
+    verify(mMockDesktopImmersiveController)
       .exitImmersiveIfApplicable(eq(binder), any(), eq(task.displayId))
   }
 
@@ -3567,10 +3572,117 @@
 
     controller.handleRequest(binder, createTransition(task))
 
-    verify(mockDesktopFullImmersiveTransitionHandler)
+    verify(mMockDesktopImmersiveController)
       .exitImmersiveIfApplicable(eq(binder), any(), eq(task.displayId))
   }
 
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+  fun shouldPlayDesktopAnimation_notShowingDesktop_doesNotPlay() {
+    val triggerTask = setUpFullscreenTask(displayId = 5)
+    taskRepository.setTaskInFullImmersiveState(
+      displayId = triggerTask.displayId,
+      taskId = triggerTask.taskId,
+      immersive = true
+    )
+
+    assertThat(controller.shouldPlayDesktopAnimation(
+      TransitionRequestInfo(TRANSIT_OPEN, triggerTask, /* remoteTransition= */ null)
+    )).isFalse()
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+  fun shouldPlayDesktopAnimation_notOpening_doesNotPlay() {
+    val triggerTask = setUpFreeformTask(displayId = 5)
+    taskRepository.setTaskInFullImmersiveState(
+      displayId = triggerTask.displayId,
+      taskId = triggerTask.taskId,
+      immersive = true
+    )
+
+    assertThat(controller.shouldPlayDesktopAnimation(
+      TransitionRequestInfo(TRANSIT_CHANGE, triggerTask, /* remoteTransition= */ null)
+    )).isFalse()
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+  fun shouldPlayDesktopAnimation_notImmersive_doesNotPlay() {
+    val triggerTask = setUpFreeformTask(displayId = 5)
+    taskRepository.setTaskInFullImmersiveState(
+      displayId = triggerTask.displayId,
+      taskId = triggerTask.taskId,
+      immersive = false
+    )
+
+    assertThat(controller.shouldPlayDesktopAnimation(
+      TransitionRequestInfo(TRANSIT_OPEN, triggerTask, /* remoteTransition= */ null)
+    )).isFalse()
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+  fun shouldPlayDesktopAnimation_fullscreenEntersDesktop_plays() {
+    // At least one freeform task to be in a desktop.
+    val existingTask = setUpFreeformTask(displayId = 5)
+    val triggerTask = setUpFullscreenTask(displayId = 5)
+    assertThat(controller.isDesktopModeShowing(triggerTask.displayId)).isTrue()
+    taskRepository.setTaskInFullImmersiveState(
+      displayId = existingTask.displayId,
+      taskId = existingTask.taskId,
+      immersive = true
+    )
+
+    assertThat(
+      controller.shouldPlayDesktopAnimation(
+        TransitionRequestInfo(TRANSIT_OPEN, triggerTask, /* remoteTransition= */ null)
+      )
+    ).isTrue()
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+  fun shouldPlayDesktopAnimation_fullscreenStaysFullscreen_doesNotPlay() {
+    val triggerTask = setUpFullscreenTask(displayId = 5)
+    assertThat(controller.isDesktopModeShowing(triggerTask.displayId)).isFalse()
+
+    assertThat(controller.shouldPlayDesktopAnimation(
+      TransitionRequestInfo(TRANSIT_OPEN, triggerTask, /* remoteTransition= */ null)
+    )).isFalse()
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+  fun shouldPlayDesktopAnimation_freeformStaysInDesktop_plays() {
+    // At least one freeform task to be in a desktop.
+    val existingTask = setUpFreeformTask(displayId = 5)
+    val triggerTask = setUpFreeformTask(displayId = 5, active = false)
+    assertThat(controller.isDesktopModeShowing(triggerTask.displayId)).isTrue()
+    taskRepository.setTaskInFullImmersiveState(
+      displayId = existingTask.displayId,
+      taskId = existingTask.taskId,
+      immersive = true
+    )
+
+    assertThat(
+      controller.shouldPlayDesktopAnimation(
+        TransitionRequestInfo(TRANSIT_OPEN, triggerTask, /* remoteTransition= */ null)
+      )
+    ).isTrue()
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+  fun shouldPlayDesktopAnimation_freeformExitsDesktop_doesNotPlay() {
+    val triggerTask = setUpFreeformTask(displayId = 5, active = false)
+    assertThat(controller.isDesktopModeShowing(triggerTask.displayId)).isFalse()
+
+    assertThat(controller.shouldPlayDesktopAnimation(
+      TransitionRequestInfo(TRANSIT_OPEN, triggerTask, /* remoteTransition= */ null)
+    )).isFalse()
+  }
+
   private class RunOnStartTransitionCallback : ((IBinder) -> Unit) {
     var invocations = 0
       private set
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
index 596b76d..fa878d0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
@@ -303,12 +303,12 @@
     }
 
     @Test
-    fun addAndGetMinimizeTaskChangesIfNeeded_tasksWithinLimit_noTaskMinimized() {
+    fun addAndGetMinimizeTaskChanges_tasksWithinLimit_noTaskMinimized() {
         (1..<MAX_TASK_LIMIT).forEach { _ -> setUpFreeformTask() }
 
         val wct = WindowContainerTransaction()
         val minimizedTaskId =
-                desktopTasksLimiter.addAndGetMinimizeTaskChangesIfNeeded(
+                desktopTasksLimiter.addAndGetMinimizeTaskChanges(
                         displayId = DEFAULT_DISPLAY,
                         wct = wct,
                         newFrontTaskId = setUpFreeformTask().taskId)
@@ -318,13 +318,13 @@
     }
 
     @Test
-    fun addAndGetMinimizeTaskChangesIfNeeded_tasksAboveLimit_backTaskMinimized() {
+    fun addAndGetMinimizeTaskChanges_tasksAboveLimit_backTaskMinimized() {
         // The following list will be ordered bottom -> top, as the last task is moved to top last.
         val tasks = (1..MAX_TASK_LIMIT).map { setUpFreeformTask() }
 
         val wct = WindowContainerTransaction()
         val minimizedTaskId =
-                desktopTasksLimiter.addAndGetMinimizeTaskChangesIfNeeded(
+                desktopTasksLimiter.addAndGetMinimizeTaskChanges(
                         displayId = DEFAULT_DISPLAY,
                         wct = wct,
                         newFrontTaskId = setUpFreeformTask().taskId)
@@ -336,13 +336,13 @@
     }
 
     @Test
-    fun addAndGetMinimizeTaskChangesIfNeeded_nonMinimizedTasksWithinLimit_noTaskMinimized() {
+    fun addAndGetMinimizeTaskChanges_nonMinimizedTasksWithinLimit_noTaskMinimized() {
         val tasks = (1..MAX_TASK_LIMIT).map { setUpFreeformTask() }
         desktopTaskRepo.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = tasks[0].taskId)
 
         val wct = WindowContainerTransaction()
         val minimizedTaskId =
-                desktopTasksLimiter.addAndGetMinimizeTaskChangesIfNeeded(
+                desktopTasksLimiter.addAndGetMinimizeTaskChanges(
                         displayId = 0,
                         wct = wct,
                         newFrontTaskId = setUpFreeformTask().taskId)
@@ -352,46 +352,46 @@
     }
 
     @Test
-    fun getTaskToMinimizeIfNeeded_tasksWithinLimit_returnsNull() {
+    fun getTaskToMinimize_tasksWithinLimit_returnsNull() {
         val tasks = (1..MAX_TASK_LIMIT).map { setUpFreeformTask() }
 
-        val minimizedTask = desktopTasksLimiter.getTaskToMinimizeIfNeeded(
-                visibleFreeformTaskIdsOrderedFrontToBack = tasks.map { it.taskId })
+        val minimizedTask = desktopTasksLimiter.getTaskToMinimize(
+                visibleOrderedTasks = tasks.map { it.taskId })
 
         assertThat(minimizedTask).isNull()
     }
 
     @Test
-    fun getTaskToMinimizeIfNeeded_tasksAboveLimit_returnsBackTask() {
+    fun getTaskToMinimize_tasksAboveLimit_returnsBackTask() {
         val tasks = (1..MAX_TASK_LIMIT + 1).map { setUpFreeformTask() }
 
-        val minimizedTask = desktopTasksLimiter.getTaskToMinimizeIfNeeded(
-                visibleFreeformTaskIdsOrderedFrontToBack = tasks.map { it.taskId })
+        val minimizedTask = desktopTasksLimiter.getTaskToMinimize(
+                visibleOrderedTasks = tasks.map { it.taskId })
 
         // first == front, last == back
         assertThat(minimizedTask).isEqualTo(tasks.last())
     }
 
     @Test
-    fun getTaskToMinimizeIfNeeded_tasksAboveLimit_otherLimit_returnsBackTask() {
+    fun getTaskToMinimize_tasksAboveLimit_otherLimit_returnsBackTask() {
         desktopTasksLimiter =
             DesktopTasksLimiter(transitions, desktopTaskRepo, shellTaskOrganizer, MAX_TASK_LIMIT2,
                 interactionJankMonitor, mContext, handler)
         val tasks = (1..MAX_TASK_LIMIT2 + 1).map { setUpFreeformTask() }
 
-        val minimizedTask = desktopTasksLimiter.getTaskToMinimizeIfNeeded(
-            visibleFreeformTaskIdsOrderedFrontToBack = tasks.map { it.taskId })
+        val minimizedTask = desktopTasksLimiter.getTaskToMinimize(
+            visibleOrderedTasks = tasks.map { it.taskId })
 
         // first == front, last == back
         assertThat(minimizedTask).isEqualTo(tasks.last())
     }
 
     @Test
-    fun getTaskToMinimizeIfNeeded_withNewTask_tasksAboveLimit_returnsBackTask() {
+    fun getTaskToMinimize_withNewTask_tasksAboveLimit_returnsBackTask() {
         val tasks = (1..MAX_TASK_LIMIT).map { setUpFreeformTask() }
 
-        val minimizedTask = desktopTasksLimiter.getTaskToMinimizeIfNeeded(
-                visibleFreeformTaskIdsOrderedFrontToBack = tasks.map { it.taskId },
+        val minimizedTask = desktopTasksLimiter.getTaskToMinimize(
+                visibleOrderedTasks = tasks.map { it.taskId },
                 newTaskIdInFront = setUpFreeformTask().taskId)
 
         // first == front, last == back
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java
index 7ae0bcd..90ab2b8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java
@@ -43,7 +43,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.window.flags.Flags;
-import com.android.wm.shell.desktopmode.DesktopFullImmersiveTransitionHandler;
+import com.android.wm.shell.desktopmode.DesktopImmersiveController;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.FocusTransitionObserver;
 import com.android.wm.shell.transition.TransitionInfoBuilder;
@@ -70,7 +70,7 @@
     @Mock
     private Transitions mTransitions;
     @Mock
-    private DesktopFullImmersiveTransitionHandler mDesktopFullImmersiveTransitionHandler;
+    private DesktopImmersiveController mDesktopImmersiveController;
     @Mock
     private WindowDecorViewModel mWindowDecorViewModel;
     @Mock
@@ -92,7 +92,7 @@
 
         mTransitionObserver = new FreeformTaskTransitionObserver(
                 context, mShellInit, mTransitions,
-                Optional.of(mDesktopFullImmersiveTransitionHandler),
+                Optional.of(mDesktopImmersiveController),
                 mWindowDecorViewModel, Optional.of(mTaskChangeListener), mFocusTransitionObserver);
 
         final ArgumentCaptor<Runnable> initRunnableCaptor = ArgumentCaptor.forClass(
@@ -321,7 +321,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
-    public void onTransitionReady_forwardsToDesktopImmersiveHandler() {
+    public void onTransitionReady_forwardsToDesktopImmersiveController() {
         final IBinder transition = mock(IBinder.class);
         final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_CHANGE, 0).build();
         final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
@@ -329,7 +329,38 @@
 
         mTransitionObserver.onTransitionReady(transition, info, startT, finishT);
 
-        verify(mDesktopFullImmersiveTransitionHandler).onTransitionReady(transition, info);
+        verify(mDesktopImmersiveController).onTransitionReady(transition, info, startT, finishT);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+    public void onTransitionMerged_forwardsToDesktopImmersiveController() {
+        final IBinder merged = mock(IBinder.class);
+        final IBinder playing = mock(IBinder.class);
+
+        mTransitionObserver.onTransitionMerged(merged, playing);
+
+        verify(mDesktopImmersiveController).onTransitionMerged(merged, playing);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+    public void onTransitionStarting_forwardsToDesktopImmersiveController() {
+        final IBinder transition = mock(IBinder.class);
+
+        mTransitionObserver.onTransitionStarting(transition);
+
+        verify(mDesktopImmersiveController).onTransitionStarting(transition);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+    public void onTransitionFinished_forwardsToDesktopImmersiveController() {
+        final IBinder transition = mock(IBinder.class);
+
+        mTransitionObserver.onTransitionFinished(transition, /* aborted= */ false);
+
+        verify(mDesktopImmersiveController).onTransitionFinished(transition, /* aborted= */ false);
     }
 
     private static TransitionInfo.Change createChange(int mode, int taskId, int windowingMode) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
index 24f6bec..a20a89c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
@@ -36,6 +36,7 @@
 import com.android.wm.shell.common.DisplayLayout
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM
+import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_LEFT
 import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT
 import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP
 import com.google.common.truth.Truth.assertThat
@@ -48,9 +49,9 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.any
-import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 import org.mockito.quality.Strictness
+import org.mockito.Mockito.`when` as whenever
 
 /**
  * Tests for [DragPositioningCallbackUtility].
@@ -193,6 +194,62 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_SCALED_RESIZING)
+    fun testChangeBounds_unresizeableApp_initialHeightLessThanMin_increasingBounds_resizeAllowed() {
+        mockWindowDecoration.mTaskInfo.isResizeable = false
+        val startingPoint = PointF(BELOW_MIN_HEIGHT_BOUNDS.right.toFloat(),
+            BELOW_MIN_HEIGHT_BOUNDS.bottom.toFloat())
+        val repositionTaskBounds = Rect(BELOW_MIN_HEIGHT_BOUNDS)
+
+        // Resize to increased bounds
+        val newX = BELOW_MIN_HEIGHT_BOUNDS.right.toFloat() + 20
+        val newY = BELOW_MIN_HEIGHT_BOUNDS.bottom.toFloat() + 10
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        // Resize should be allowed as drag is in direction of desired range
+        assertTrue(
+            DragPositioningCallbackUtility.changeBounds(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+                repositionTaskBounds, BELOW_MIN_HEIGHT_BOUNDS, STABLE_BOUNDS, delta,
+                mockDisplayController, mockWindowDecoration
+            )
+        )
+
+        assertThat(repositionTaskBounds.left).isEqualTo(BELOW_MIN_HEIGHT_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(BELOW_MIN_HEIGHT_BOUNDS.top)
+        assertThat(repositionTaskBounds.right).isEqualTo(BELOW_MIN_HEIGHT_BOUNDS.right + 20)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(BELOW_MIN_HEIGHT_BOUNDS.bottom + 10)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_SCALED_RESIZING)
+    fun testChangeBounds_unresizeableApp_initialHeightMoreThanMax_decreasingBounds_resizeAllowed() {
+        mockWindowDecoration.mTaskInfo.isResizeable = false
+        val startingPoint = PointF(EXCEEDS_MAX_HEIGHT_BOUNDS.right.toFloat(),
+            EXCEEDS_MAX_HEIGHT_BOUNDS.top.toFloat())
+        val repositionTaskBounds = Rect(EXCEEDS_MAX_HEIGHT_BOUNDS)
+
+        // Resize to decreased bounds.
+        val newX = EXCEEDS_MAX_HEIGHT_BOUNDS.right.toFloat() - 10
+        val newY = EXCEEDS_MAX_HEIGHT_BOUNDS.top.toFloat() + 20
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        // Resize should be allowed as drag is in direction of desired range.
+        assertTrue(
+            DragPositioningCallbackUtility.changeBounds(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+                repositionTaskBounds, EXCEEDS_MAX_HEIGHT_BOUNDS, STABLE_BOUNDS, delta,
+                mockDisplayController, mockWindowDecoration
+            )
+        )
+
+        assertThat(repositionTaskBounds.left).isEqualTo(EXCEEDS_MAX_HEIGHT_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(EXCEEDS_MAX_HEIGHT_BOUNDS.top + 20)
+        assertThat(repositionTaskBounds.right).isEqualTo(EXCEEDS_MAX_HEIGHT_BOUNDS.right - 10)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(EXCEEDS_MAX_HEIGHT_BOUNDS.bottom)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_SCALED_RESIZING)
     fun testChangeBounds_unresizeableApp_widthLessThanMin_resetToStartingBounds() {
         mockWindowDecoration.mTaskInfo.isResizeable = false
         val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
@@ -211,13 +268,68 @@
             )
         )
 
-
         assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
         assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
         assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right)
         assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom)
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_SCALED_RESIZING)
+    fun testChangeBounds_unresizeableApp_initialWidthLessThanMin_increasingBounds_resizeAllowed() {
+        mockWindowDecoration.mTaskInfo.isResizeable = false
+        val startingPoint = PointF(BELOW_MIN_WIDTH_BOUNDS.right.toFloat(),
+            BELOW_MIN_WIDTH_BOUNDS.bottom.toFloat())
+        val repositionTaskBounds = Rect(BELOW_MIN_WIDTH_BOUNDS)
+
+        // Resize to increased bounds.
+        val newX = BELOW_MIN_WIDTH_BOUNDS.right.toFloat() + 10
+        val newY = BELOW_MIN_WIDTH_BOUNDS.bottom.toFloat() + 20
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        // Resize should be allowed as drag is in direction of desired range.
+        assertTrue(
+            DragPositioningCallbackUtility.changeBounds(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+                repositionTaskBounds, BELOW_MIN_WIDTH_BOUNDS, STABLE_BOUNDS, delta,
+                mockDisplayController, mockWindowDecoration
+            )
+        )
+
+        assertThat(repositionTaskBounds.left).isEqualTo(BELOW_MIN_WIDTH_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(BELOW_MIN_WIDTH_BOUNDS.top)
+        assertThat(repositionTaskBounds.right).isEqualTo(BELOW_MIN_WIDTH_BOUNDS.right + 10)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(BELOW_MIN_WIDTH_BOUNDS.bottom + 20)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_SCALED_RESIZING)
+    fun testChangeBounds_unresizeableApp_initialWidthMoreThanMax_decreasingBounds_resizeAllowed() {
+        mockWindowDecoration.mTaskInfo.isResizeable = false
+        val startingPoint = PointF(EXCEEDS_MAX_WIDTH_BOUNDS.left.toFloat(),
+            EXCEEDS_MAX_WIDTH_BOUNDS.top.toFloat())
+        val repositionTaskBounds = Rect(EXCEEDS_MAX_WIDTH_BOUNDS)
+
+        // Resize to decreased bounds.
+        val newX = EXCEEDS_MAX_WIDTH_BOUNDS.left.toFloat() + 20
+        val newY = EXCEEDS_MAX_WIDTH_BOUNDS.top.toFloat() + 10
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        // Resize should be allowed as drag is in direction of desired range.
+        assertTrue(
+            DragPositioningCallbackUtility.changeBounds(
+                CTRL_TYPE_LEFT or CTRL_TYPE_TOP,
+                repositionTaskBounds, EXCEEDS_MAX_WIDTH_BOUNDS, STABLE_BOUNDS, delta,
+                mockDisplayController, mockWindowDecoration
+            )
+        )
+
+        assertThat(repositionTaskBounds.left).isEqualTo(EXCEEDS_MAX_WIDTH_BOUNDS.left + 20)
+        assertThat(repositionTaskBounds.top).isEqualTo(EXCEEDS_MAX_WIDTH_BOUNDS.top + 10)
+        assertThat(repositionTaskBounds.right).isEqualTo(EXCEEDS_MAX_WIDTH_BOUNDS.right)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(EXCEEDS_MAX_WIDTH_BOUNDS.bottom)
+    }
+
 
     @Test
     fun testChangeBoundsDoesNotChangeHeightWhenNegative() {
@@ -427,6 +539,60 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
+    fun testMinHeight_initialHeightLessThanMin_increasingHeight_resizeAllowed() {
+        val startingPoint = PointF(BELOW_MIN_HEIGHT_BOUNDS.right.toFloat(),
+            BELOW_MIN_HEIGHT_BOUNDS.bottom.toFloat())
+        val repositionTaskBounds = Rect(BELOW_MIN_HEIGHT_BOUNDS)
+
+        // Attempt to increase height.
+        val newX = BELOW_MIN_HEIGHT_BOUNDS.right.toFloat()
+        val newY = BELOW_MIN_HEIGHT_BOUNDS.bottom.toFloat() + 10
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        // Resize should be allowed as drag is increasing height closer to valid region.
+        assertTrue(
+            DragPositioningCallbackUtility.changeBounds(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+                repositionTaskBounds, BELOW_MIN_HEIGHT_BOUNDS, STABLE_BOUNDS, delta,
+                mockDisplayController, mockWindowDecoration
+            )
+        )
+
+        assertThat(repositionTaskBounds.left).isEqualTo(BELOW_MIN_HEIGHT_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(BELOW_MIN_HEIGHT_BOUNDS.top)
+        assertThat(repositionTaskBounds.right).isEqualTo(BELOW_MIN_HEIGHT_BOUNDS.right)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(BELOW_MIN_HEIGHT_BOUNDS.bottom + 10)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
+    fun testMinWidth_initialWidthLessThanMin_increasingBounds_resizeAllowed() {
+        val startingPoint = PointF(BELOW_MIN_WIDTH_BOUNDS.right.toFloat(),
+            BELOW_MIN_WIDTH_BOUNDS.bottom.toFloat())
+        val repositionTaskBounds = Rect(BELOW_MIN_WIDTH_BOUNDS)
+
+        // Attempt to increase width.
+        val newX = BELOW_MIN_WIDTH_BOUNDS.right.toFloat() + 10
+        val newY = BELOW_MIN_WIDTH_BOUNDS.bottom.toFloat()
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        // Resize should be allowed as drag is increasing width closer to valid region.
+        assertTrue(
+            DragPositioningCallbackUtility.changeBounds(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+                repositionTaskBounds, BELOW_MIN_WIDTH_BOUNDS, STABLE_BOUNDS, delta,
+                mockDisplayController, mockWindowDecoration
+            )
+        )
+
+        assertThat(repositionTaskBounds.left).isEqualTo(BELOW_MIN_WIDTH_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(BELOW_MIN_WIDTH_BOUNDS.top)
+        assertThat(repositionTaskBounds.right).isEqualTo(BELOW_MIN_WIDTH_BOUNDS.right + 10)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(BELOW_MIN_WIDTH_BOUNDS.bottom)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
     fun taskMinWidthHeightUndefined_changeBoundsInDesktopModeAllowedSize_shouldChangeBounds() {
         doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(mockContext) }
         initializeTaskInfo(taskMinWidth = -1, taskMinHeight = -1)
@@ -547,6 +713,61 @@
         assertThat(repositionTaskBounds.height()).isLessThan(STABLE_BOUNDS.bottom)
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
+    fun testMaxHeight_initialHeightMoreThanMax_decreasingHeight_resizeAllowed() {
+        mockWindowDecoration.mTaskInfo.isResizeable = false
+        val startingPoint = PointF(EXCEEDS_MAX_HEIGHT_BOUNDS.right.toFloat(),
+            EXCEEDS_MAX_HEIGHT_BOUNDS.top.toFloat())
+        val repositionTaskBounds = Rect(EXCEEDS_MAX_HEIGHT_BOUNDS)
+
+        // Attempt to decrease height
+        val newX = EXCEEDS_MAX_HEIGHT_BOUNDS.right.toFloat() - 10
+        val newY = EXCEEDS_MAX_HEIGHT_BOUNDS.top.toFloat()
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        // Resize should be allowed as drag is decreasing height closer to valid region.
+        assertTrue(
+            DragPositioningCallbackUtility.changeBounds(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+                repositionTaskBounds, EXCEEDS_MAX_HEIGHT_BOUNDS, STABLE_BOUNDS, delta,
+                mockDisplayController, mockWindowDecoration
+            )
+        )
+
+        assertThat(repositionTaskBounds.left).isEqualTo(EXCEEDS_MAX_HEIGHT_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(EXCEEDS_MAX_HEIGHT_BOUNDS.top)
+        assertThat(repositionTaskBounds.right).isEqualTo(EXCEEDS_MAX_HEIGHT_BOUNDS.right - 10)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(EXCEEDS_MAX_HEIGHT_BOUNDS.bottom )
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
+    fun testMaxHeight_initialWidthMoreThanMax_decreasingBounds_resizeAllowed() {
+        val startingPoint = PointF(EXCEEDS_MAX_WIDTH_BOUNDS.left.toFloat(),
+            EXCEEDS_MAX_WIDTH_BOUNDS.top.toFloat())
+        val repositionTaskBounds = Rect(EXCEEDS_MAX_WIDTH_BOUNDS)
+
+        // Attempt to decrease width.
+        val newX = EXCEEDS_MAX_WIDTH_BOUNDS.left.toFloat() + 20
+        val newY = EXCEEDS_MAX_WIDTH_BOUNDS.top.toFloat()
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        // Resize should be allowed as drag is decreasing width closer to valid region.
+        assertTrue(
+            DragPositioningCallbackUtility.changeBounds(
+                CTRL_TYPE_LEFT or CTRL_TYPE_TOP,
+                repositionTaskBounds, EXCEEDS_MAX_WIDTH_BOUNDS, STABLE_BOUNDS, delta,
+                mockDisplayController, mockWindowDecoration
+            )
+        )
+
+        assertThat(repositionTaskBounds.left).isEqualTo(EXCEEDS_MAX_WIDTH_BOUNDS.left + 20)
+        assertThat(repositionTaskBounds.top).isEqualTo(EXCEEDS_MAX_WIDTH_BOUNDS.top)
+        assertThat(repositionTaskBounds.right).isEqualTo(EXCEEDS_MAX_WIDTH_BOUNDS.right)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(EXCEEDS_MAX_WIDTH_BOUNDS.bottom)
+    }
+
     private fun initializeTaskInfo(taskMinWidth: Int = MIN_WIDTH, taskMinHeight: Int = MIN_HEIGHT) {
         mockWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply {
             taskId = TASK_ID
@@ -571,6 +792,10 @@
         private const val NAVBAR_HEIGHT = 50
         private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
         private val STARTING_BOUNDS = Rect(0, 0, 100, 100)
+        private val BELOW_MIN_WIDTH_BOUNDS = Rect(0, 0, 50, 100)
+        private val BELOW_MIN_HEIGHT_BOUNDS = Rect(0, 0, 100, 50)
+        private val EXCEEDS_MAX_WIDTH_BOUNDS = Rect(0, 0, 3000, 1500)
+        private val EXCEEDS_MAX_HEIGHT_BOUNDS = Rect(0, 0, 1000, 2000)
         private val OFF_CENTER_STARTING_BOUNDS = Rect(-100, -100, 10, 10)
         private val DISALLOWED_RESIZE_AREA = Rect(
             DISPLAY_BOUNDS.left,
diff --git a/libs/protoutil/Android.bp b/libs/protoutil/Android.bp
index 28856c8..8af4b7e 100644
--- a/libs/protoutil/Android.bp
+++ b/libs/protoutil/Android.bp
@@ -60,6 +60,7 @@
         "//apex_available:platform",
         "com.android.os.statsd",
         "test_com.android.os.statsd",
+        "com.android.uprobestats",
     ],
 }
 
diff --git a/media/java/android/media/AudioDeviceVolumeManager.java b/media/java/android/media/AudioDeviceVolumeManager.java
index 13876ad..e1fbfea 100644
--- a/media/java/android/media/AudioDeviceVolumeManager.java
+++ b/media/java/android/media/AudioDeviceVolumeManager.java
@@ -16,8 +16,11 @@
 
 package android.media;
 
+import static com.android.media.flags.Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL;
+
 import android.Manifest;
 import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -434,6 +437,83 @@
 
     /**
      * @hide
+     * Sets the input gain index for a particular AudioDeviceAttributes.
+     * TODO(b/364923030): create InputVolumeInfo on top of VolumeInfo rather than using index to
+     * handle volume information, to solve issues e.g. gain index ranges might be different for
+     * different categories of devices.
+     */
+    @FlaggedApi(FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public void setInputGainIndex(@NonNull AudioDeviceAttributes ada, int index) {
+        try {
+            getService().setInputGainIndex(ada, index);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Gets the input gain index for a particular AudioDeviceAttributes.
+     */
+    @FlaggedApi(FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public int getInputGainIndex(@NonNull AudioDeviceAttributes ada) {
+        try {
+            return getService().getInputGainIndex(ada);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Gets the maximum input gain index for input device.
+     */
+    @FlaggedApi(FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public int getMaxInputGainIndex() {
+        try {
+            return getService().getMaxInputGainIndex();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Gets the minimum input gain index for input device.
+     */
+    @FlaggedApi(FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public int getMinInputGainIndex() {
+        try {
+            return getService().getMinInputGainIndex();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Indicates if an input device does not support input gain control.
+     *     <p>The following APIs have no effect when input gain is fixed:
+     *     <ul>
+     *       <li>{@link #setInputGainIndex(AudioDeviceAttributes, int)}
+     *     </ul>
+     */
+    @FlaggedApi(FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public boolean isInputGainFixed(@NonNull AudioDeviceAttributes ada) {
+        try {
+            return getService().isInputGainFixed(ada);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
      * Return human-readable name for volume behavior
      * @param behavior one of the volume behaviors defined in AudioManager
      * @return a string for the given behavior
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index c22b674..9fd3f5b 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -189,6 +189,21 @@
 
     void setMicrophoneMute(boolean on, String callingPackage, int userId, in String attributionTag);
 
+    @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
+    void setInputGainIndex(in AudioDeviceAttributes ada, int index);
+
+    @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
+    int getInputGainIndex(in AudioDeviceAttributes ada);
+
+    @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
+    int getMaxInputGainIndex();
+
+    @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
+    int getMinInputGainIndex();
+
+    @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
+    boolean isInputGainFixed(in AudioDeviceAttributes ada);
+
     oneway void setMicrophoneMuteFromSwitch(boolean on);
 
     void setRingerModeExternal(int ringerMode, String caller);
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 8ff4305..3a19f46 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -462,6 +462,33 @@
         @SuppressLint("AllUpper")
         public static final int COLOR_FormatYUVP010                 = 54;
 
+        /**
+         * P210 is 10-bit-per component 4:2:2 YCbCr semiplanar format.
+         * <p>
+         * This format uses 32 allocated bits per pixel with 20 bits of
+         * data per pixel. Chroma planes are subsampled by 2 both
+         * horizontally. Each chroma and luma component
+         * has 16 allocated bits in little-endian configuration with 10
+         * MSB of actual data.
+         *
+         * <pre>
+         *            byte                   byte
+         *  <--------- i --------> | <------ i + 1 ------>
+         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+         * |     UNUSED      |      Y/Cb/Cr                |
+         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+         *  0               5 6   7 0                    7
+         * bit
+         * </pre>
+         *
+         * Use this format with {@link Image}. This format corresponds
+         * to {@link android.graphics.ImageFormat#YCBCR_P210}.
+         * <p>
+         */
+        @SuppressLint("AllUpper")
+        @FlaggedApi(android.media.codec.Flags.FLAG_P210_FORMAT_SUPPORT)
+        public static final int COLOR_FormatYUVP210                 = 60;
+
         /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
         public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100;
         // COLOR_FormatSurface indicates that the data will be a GraphicBuffer metadata reference.
diff --git a/media/java/android/media/Utils.java b/media/java/android/media/Utils.java
index 41e9b65..11bd221 100644
--- a/media/java/android/media/Utils.java
+++ b/media/java/android/media/Utils.java
@@ -719,6 +719,9 @@
      * @return {@code true} if the Uri has vibration parameter
      */
     public static boolean hasVibration(Uri ringtoneUri) {
+        if (ringtoneUri == null) {
+            return false;
+        }
         final String vibrationUriString = ringtoneUri.getQueryParameter(VIBRATION_URI_PARAM);
         return vibrationUriString != null;
     }
@@ -730,7 +733,10 @@
      * @return parsed {@link Uri} of vibration parameter, {@code null} if the vibration parameter
      * is not found.
      */
-    public static Uri getVibrationUri(Uri ringtoneUri) {
+    public static @Nullable Uri getVibrationUri(Uri ringtoneUri) {
+        if (ringtoneUri == null) {
+            return null;
+        }
         final String vibrationUriString = ringtoneUri.getQueryParameter(VIBRATION_URI_PARAM);
         if (vibrationUriString == null) {
             return null;
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
index fd677ac..898a8bf 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
+++ b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
@@ -16,11 +16,13 @@
 
 package android.media.tv.tuner.frontend;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
+import android.media.tv.flags.Flags;
 import android.media.tv.tuner.Lnb;
 import android.media.tv.tuner.TunerVersionChecker;
 
@@ -61,7 +63,7 @@
             FRONTEND_STATUS_TYPE_DVBT_CELL_IDS, FRONTEND_STATUS_TYPE_ATSC3_ALL_PLP_INFO,
             FRONTEND_STATUS_TYPE_IPTV_CONTENT_URL, FRONTEND_STATUS_TYPE_IPTV_PACKETS_LOST,
             FRONTEND_STATUS_TYPE_IPTV_PACKETS_RECEIVED, FRONTEND_STATUS_TYPE_IPTV_WORST_JITTER_MS,
-            FRONTEND_STATUS_TYPE_IPTV_AVERAGE_JITTER_MS})
+            FRONTEND_STATUS_TYPE_IPTV_AVERAGE_JITTER_MS, FRONTEND_STATUS_TYPE_STANDARD_EXT})
     @Retention(RetentionPolicy.SOURCE)
     public @interface FrontendStatusType {}
 
@@ -311,6 +313,13 @@
     public static final int FRONTEND_STATUS_TYPE_ATSC3_ALL_PLP_INFO =
             android.hardware.tv.tuner.FrontendStatusType.ATSC3_ALL_PLP_INFO;
 
+    /**
+     * Standard extension.
+     */
+    @FlaggedApi(Flags.FLAG_TUNER_W_APIS)
+    public static final int FRONTEND_STATUS_TYPE_STANDARD_EXT =
+            android.hardware.tv.tuner.FrontendStatusType.STANDARD_EXT;
+
     /** @hide */
     @IntDef(value = {
             AtscFrontendSettings.MODULATION_UNDEFINED,
@@ -558,6 +567,7 @@
     private Long mIptvPacketsReceived;
     private Integer mIptvWorstJitterMs;
     private Integer mIptvAverageJitterMs;
+    private StandardExt mStandardExt;
 
     // Constructed and fields set by JNI code.
     private FrontendStatus() {
@@ -1273,4 +1283,27 @@
         }
         return mIptvAverageJitterMs;
     }
+    /**
+     * Gets the standard extension.
+     *
+     * <p>The tuner standard DVB-T has the extension DVB-T2, and the standard DVB-S has the
+     * extensions DVB-S2 and DVB-S2X. This method returns the current standard extension within the
+     * same standard series. This frontend status is reported when the standard extension
+     * transitions to another during playback.
+     *
+     * <p>This query is supported only by Tuner HAL 4.0 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     *
+     * @return The current standard extension.
+     */
+    @NonNull
+    @FlaggedApi(Flags.FLAG_TUNER_W_APIS)
+    public StandardExt getStandardExt() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_4_0, "StandardExt status");
+        if (mStandardExt == null) {
+            throw new IllegalStateException("StandardExt status is empty");
+        }
+        return mStandardExt;
+    }
 }
diff --git a/media/java/android/media/tv/tuner/frontend/StandardExt.java b/media/java/android/media/tv/tuner/frontend/StandardExt.java
new file mode 100644
index 0000000..4907272
--- /dev/null
+++ b/media/java/android/media/tv/tuner/frontend/StandardExt.java
@@ -0,0 +1,75 @@
+/*
+ * 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.media.tv.tuner.frontend;
+
+import android.annotation.FlaggedApi;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.FrontendDvbsStandard;
+import android.hardware.tv.tuner.FrontendDvbtStandard;
+import android.media.tv.flags.Flags;
+
+/**
+ * Standard extension for the standard DVB-T and DVB-S series.
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_TUNER_W_APIS)
+public final class StandardExt {
+    private final int mDvbsStandardExt;
+    private final int mDvbtStandardExt;
+
+    /**
+     * Private constructor called by JNI only.
+     */
+    private StandardExt(int dvbsStandardExt, int dvbtStandardExt) {
+        mDvbsStandardExt = dvbsStandardExt;
+        mDvbtStandardExt = dvbtStandardExt;
+    }
+
+    /**
+     * Gets the DVB-S standard extension within the DVB-S standard series.
+     *
+     * @return An integer representing the standard, such as
+     * {@link DvbsFrontendSettings#STANDARD_S}.
+     *
+     * @see android.media.tv.tuner.frontend.DvbsFrontendSettings
+     */
+    @DvbsFrontendSettings.Standard
+    public int getDvbsStandardExt() {
+        if (mDvbsStandardExt == FrontendDvbsStandard.UNDEFINED) {
+            throw new IllegalStateException("No DVB-S standard transition");
+        }
+        return mDvbsStandardExt;
+    }
+
+    /**
+     * Gets the DVB-T standard extension within the DVB-T standard series.
+     *
+     * @return An integer representing the standard, such as
+     * {@link DvbtFrontendSettings#STANDARD_T}.
+     *
+     * @see android.media.tv.tuner.frontend.DvbtFrontendSettings
+     */
+    @DvbtFrontendSettings.Standard
+    public int getDvbtStandardExt() {
+        if (mDvbtStandardExt == FrontendDvbtStandard.UNDEFINED) {
+            throw new IllegalStateException("No DVB-T standard transition");
+        }
+        return mDvbtStandardExt;
+    }
+}
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 9e1e2c3..80ca4f2 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -144,6 +144,7 @@
 #include <aidl/android/hardware/tv/tuner/FrontendScanAtsc3PlpInfo.h>
 #include <aidl/android/hardware/tv/tuner/FrontendScanMessageStandard.h>
 #include <aidl/android/hardware/tv/tuner/FrontendSpectralInversion.h>
+#include <aidl/android/hardware/tv/tuner/FrontendStandardExt.h>
 #include <aidl/android/hardware/tv/tuner/FrontendStatus.h>
 #include <aidl/android/hardware/tv/tuner/FrontendStatusAtsc3PlpInfo.h>
 #include <aidl/android/hardware/tv/tuner/FrontendStatusType.h>
@@ -302,6 +303,7 @@
 using ::aidl::android::hardware::tv::tuner::FrontendScanAtsc3PlpInfo;
 using ::aidl::android::hardware::tv::tuner::FrontendScanMessageStandard;
 using ::aidl::android::hardware::tv::tuner::FrontendSpectralInversion;
+using ::aidl::android::hardware::tv::tuner::FrontendStandardExt;
 using ::aidl::android::hardware::tv::tuner::FrontendStatus;
 using ::aidl::android::hardware::tv::tuner::FrontendStatusAtsc3PlpInfo;
 using ::aidl::android::hardware::tv::tuner::FrontendStatusType;
@@ -2937,6 +2939,33 @@
                 env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
+            case FrontendStatus::Tag::standardExt: {
+                jfieldID field = env->GetFieldID(clazz, "mStandardExt",
+                        "Landroid/media/tv/tuner/frontend/StandardExt;");
+                ScopedLocalRef standardExtClazz(env,
+                        env->FindClass("android/media/tv/tuner/frontend/StandardExt"));
+                jmethodID initStandardExt = env->GetMethodID(standardExtClazz.get(), "<init>",
+                        "(II)V");
+
+                jint dvbsStandardExt = static_cast<jint>(FrontendDvbsStandard::UNDEFINED);
+                jint dvbtStandardExt = static_cast<jint>(FrontendDvbtStandard::UNDEFINED);
+                FrontendStandardExt standardExt = s.get<FrontendStatus::Tag::standardExt>();
+                switch (standardExt.getTag()) {
+                    case FrontendStandardExt::Tag::dvbsStandardExt: {
+                        dvbsStandardExt = static_cast<jint>(standardExt
+                                .get<FrontendStandardExt::Tag::dvbsStandardExt>());
+                        break;
+                    }
+                    case FrontendStandardExt::Tag::dvbtStandardExt: {
+                        dvbtStandardExt = static_cast<jint>(standardExt
+                                .get<FrontendStandardExt::Tag::dvbtStandardExt>());
+                        break;
+                    }
+                }
+                ScopedLocalRef standardExtObj(env, env->NewObject(standardExtClazz.get(),
+                        initStandardExt, dvbsStandardExt, dvbtStandardExt));
+                env->SetObjectField(statusObj, field, standardExtObj.get());
+            }
         }
     }
     return statusObj;
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 095d7d1..15f77ce 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -39,6 +39,7 @@
 #include <utils/SystemClock.h>
 
 #include <chrono>
+#include <future>
 #include <set>
 #include <utility>
 #include <vector>
@@ -104,6 +105,7 @@
     size_t mAvailableSlots GUARDED_BY(sHintMutex) = 0;
     bool mHalSupported = true;
     HalMessageQueue::MemTransaction mFmqTransaction GUARDED_BY(sHintMutex);
+    std::future<bool> mChannelCreationFinished;
 };
 
 struct APerformanceHintManager {
@@ -218,6 +220,8 @@
 }
 
 APerformanceHintManager* APerformanceHintManager::getInstance() {
+    static std::once_flag creationFlag;
+    static APerformanceHintManager* instance = nullptr;
     if (gHintManagerForTesting) {
         return gHintManagerForTesting.get();
     }
@@ -226,7 +230,7 @@
                 std::shared_ptr<APerformanceHintManager>(create(*gIHintManagerForTesting));
         return gHintManagerForTesting.get();
     }
-    static APerformanceHintManager* instance = create(nullptr);
+    std::call_once(creationFlag, []() { instance = create(nullptr); });
     return instance;
 }
 
@@ -522,25 +526,28 @@
 }
 
 bool FMQWrapper::startChannel(IHintManager* manager) {
-    if (isSupported() && !isActive()) {
-        std::optional<hal::ChannelConfig> config;
-        auto ret = manager->getSessionChannel(mToken, &config);
-        if (ret.isOk() && config.has_value()) {
-            std::scoped_lock lock{sHintMutex};
-            mQueue = std::make_shared<HalMessageQueue>(config->channelDescriptor, true);
-            if (config->eventFlagDescriptor.has_value()) {
-                mFlagQueue = std::make_shared<HalFlagQueue>(*config->eventFlagDescriptor, true);
-                android::hardware::EventFlag::createEventFlag(mFlagQueue->getEventFlagWord(),
-                                                              &mEventFlag);
-                mWriteMask = config->writeFlagBitmask;
+    if (isSupported() && !isActive() && manager->isRemote()) {
+        mChannelCreationFinished = std::async(std::launch::async, [&, this, manager]() {
+            std::optional<hal::ChannelConfig> config;
+            auto ret = manager->getSessionChannel(mToken, &config);
+            if (ret.isOk() && config.has_value()) {
+                std::scoped_lock lock{sHintMutex};
+                mQueue = std::make_shared<HalMessageQueue>(config->channelDescriptor, true);
+                if (config->eventFlagDescriptor.has_value()) {
+                    mFlagQueue = std::make_shared<HalFlagQueue>(*config->eventFlagDescriptor, true);
+                    android::hardware::EventFlag::createEventFlag(mFlagQueue->getEventFlagWord(),
+                                                                  &mEventFlag);
+                    mWriteMask = config->writeFlagBitmask;
+                }
+                updatePersistentTransaction();
+            } else if (ret.isOk() && !config.has_value()) {
+                ALOGV("FMQ channel enabled but unsupported.");
+                setUnsupported();
+            } else {
+                ALOGE("%s: FMQ channel initialization failed: %s", __FUNCTION__, ret.getMessage());
             }
-            updatePersistentTransaction();
-        } else if (ret.isOk() && !config.has_value()) {
-            ALOGV("FMQ channel enabled but unsupported.");
-            setUnsupported();
-        } else {
-            ALOGE("%s: FMQ channel initialization failed: %s", __FUNCTION__, ret.getMessage());
-        }
+            return true;
+        });
     }
     return isActive();
 }
diff --git a/omapi/aidl/vts/functional/AccessControlApp/Android.bp b/omapi/aidl/vts/functional/AccessControlApp/Android.bp
index f03c3f6..57d75f5 100644
--- a/omapi/aidl/vts/functional/AccessControlApp/Android.bp
+++ b/omapi/aidl/vts/functional/AccessControlApp/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_fwk_nfc",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/omapi/aidl/vts/functional/omapi/Android.bp b/omapi/aidl/vts/functional/omapi/Android.bp
index c41479f..8ee55ff 100644
--- a/omapi/aidl/vts/functional/omapi/Android.bp
+++ b/omapi/aidl/vts/functional/omapi/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_fwk_nfc",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
index 9a8261c..8e5ae20 100644
--- a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
@@ -24,9 +24,12 @@
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -94,6 +97,8 @@
  * be notified.
  * @hide
  */
+@FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY)
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
 public class PackageWatchdog {
     private static final String TAG = "PackageWatchdog";
 
@@ -351,7 +356,7 @@
      *
      * <p>If monitoring a package supporting explicit health check, at the end of the monitoring
      * duration if {@link #onHealthCheckPassed} was never called,
-     * {@link PackageHealthObserver#execute} will be called as if the package failed.
+     * {@link PackageHealthObserver#onExecuteHealthCheckMitigation} will be called as if the package failed.
      *
      * <p>If {@code observer} is already monitoring a package in {@code packageNames},
      * the monitoring window of that package will be reset to {@code durationMs} and the health
@@ -514,8 +519,8 @@
                                 maybeExecute(currentObserverToNotify, versionedPackage,
                                         failureReason, currentObserverImpact, mitigationCount);
                             } else {
-                                currentObserverToNotify.execute(versionedPackage,
-                                        failureReason, mitigationCount);
+                                currentObserverToNotify.onExecuteHealthCheckMitigation(
+                                        versionedPackage, failureReason, mitigationCount);
                             }
                         }
                     }
@@ -550,7 +555,8 @@
                 maybeExecute(currentObserverToNotify, failingPackage, failureReason,
                         currentObserverImpact, /*mitigationCount=*/ 1);
             } else {
-                currentObserverToNotify.execute(failingPackage,  failureReason, 1);
+                currentObserverToNotify.onExecuteHealthCheckMitigation(failingPackage,
+                        failureReason, 1);
             }
         }
     }
@@ -564,7 +570,8 @@
             synchronized (mLock) {
                 mLastMitigation = mSystemClock.uptimeMillis();
             }
-            currentObserverToNotify.execute(versionedPackage, failureReason, mitigationCount);
+            currentObserverToNotify.onExecuteHealthCheckMitigation(versionedPackage, failureReason,
+                    mitigationCount);
         }
     }
 
@@ -626,12 +633,12 @@
                         currentObserverInternal.setBootMitigationCount(
                                 currentObserverMitigationCount);
                         saveAllObserversBootMitigationCountToMetadata(METADATA_FILE);
-                        currentObserverToNotify.executeBootLoopMitigation(
+                        currentObserverToNotify.onExecuteBootLoopMitigation(
                                 currentObserverMitigationCount);
                     } else {
                         mBootThreshold.setMitigationCount(mitigationCount);
                         mBootThreshold.saveMitigationCountToMetadata();
-                        currentObserverToNotify.executeBootLoopMitigation(mitigationCount);
+                        currentObserverToNotify.onExecuteBootLoopMitigation(mitigationCount);
                     }
                 }
             }
@@ -717,7 +724,9 @@
         return mPackagesExemptFromImpactLevelThreshold;
     }
 
-    /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}.
+    /**
+     * Possible severity values of the user impact of a
+     * {@link PackageHealthObserver#onExecuteHealthCheckMitigation}.
      * @hide
      */
     @Retention(SOURCE)
@@ -753,6 +762,7 @@
     }
 
     /** Register instances of this interface to receive notifications on package failure. */
+    @SuppressLint({"CallbackName"})
     public interface PackageHealthObserver {
         /**
          * Called when health check fails for the {@code versionedPackage}.
@@ -765,7 +775,7 @@
          *
          *
          * @return any one of {@link PackageHealthObserverImpact} to express the impact
-         * to the user on {@link #execute}
+         * to the user on {@link #onExecuteHealthCheckMitigation}
          */
         @PackageHealthObserverImpact int onHealthCheckFailed(
                 @Nullable VersionedPackage versionedPackage,
@@ -773,7 +783,10 @@
                 int mitigationCount);
 
         /**
-         * Executes mitigation for {@link #onHealthCheckFailed}.
+         * This would be called after {@link #onHealthCheckFailed}.
+         * This is called only if current observer returned least
+         * {@link PackageHealthObserverImpact} mitigation for failed health
+         * check.
          *
          * @param versionedPackage the package that is failing. This may be null if a native
          *                          service is crashing.
@@ -782,7 +795,7 @@
          *                        (including this time).
          * @return {@code true} if action was executed successfully, {@code false} otherwise
          */
-        boolean execute(@Nullable VersionedPackage versionedPackage,
+        boolean onExecuteHealthCheckMitigation(@Nullable VersionedPackage versionedPackage,
                 @FailureReasons int failureReason, int mitigationCount);
 
 
@@ -798,11 +811,14 @@
         }
 
         /**
-         * Executes mitigation for {@link #onBootLoop}
+         * This would be called after {@link #onBootLoop}.
+         * This is called only if current observer returned least
+         * {@link PackageHealthObserverImpact} mitigation for fixing boot loop
+         *
          * @param mitigationCount the number of times mitigation has been attempted for this
          *                        boot loop (including this time).
          */
-        default boolean executeBootLoopMitigation(int mitigationCount) {
+        default boolean onExecuteBootLoopMitigation(int mitigationCount) {
             return false;
         }
 
@@ -1083,7 +1099,7 @@
                         if (versionedPkg != null) {
                             Slog.i(TAG,
                                     "Explicit health check failed for package " + versionedPkg);
-                            registeredObserver.execute(versionedPkg,
+                            registeredObserver.onExecuteHealthCheckMitigation(versionedPkg,
                                     PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK, 1);
                         }
                     }
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/module/java/com/android/server/RescueParty.java
index f1b2f6b..f1103e1 100644
--- a/packages/CrashRecovery/services/module/java/com/android/server/RescueParty.java
+++ b/packages/CrashRecovery/services/module/java/com/android/server/RescueParty.java
@@ -728,7 +728,7 @@
         }
 
         @Override
-        public boolean execute(@Nullable VersionedPackage failedPackage,
+        public boolean onExecuteHealthCheckMitigation(@Nullable VersionedPackage failedPackage,
                 @FailureReasons int failureReason, int mitigationCount) {
             if (isDisabled()) {
                 return false;
@@ -796,7 +796,7 @@
         }
 
         @Override
-        public boolean executeBootLoopMitigation(int mitigationCount) {
+        public boolean onExecuteBootLoopMitigation(int mitigationCount) {
             if (isDisabled()) {
                 return false;
             }
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/packages/CrashRecovery/services/module/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 2931652..8277e57 100644
--- a/packages/CrashRecovery/services/module/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/packages/CrashRecovery/services/module/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -19,8 +19,11 @@
 import static com.android.server.crashrecovery.CrashRecoveryUtils.logCrashRecoveryEvent;
 
 import android.annotation.AnyThread;
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
 import android.annotation.WorkerThread;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
@@ -75,6 +78,9 @@
  *
  * @hide
  */
+@FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY)
+@SuppressLint({"CallbackName"})
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
 public final class RollbackPackageHealthObserver implements PackageHealthObserver {
     private static final String TAG = "RollbackPackageHealthObserver";
     private static final String NAME = "rollback-observer";
@@ -148,7 +154,7 @@
                 // Note: For non-native crashes the rollback-all step has higher impact
                 impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_30;
             } else if (getAvailableRollback(failedPackage) != null) {
-                // Rollback is available, we may get a callback into #execute
+                // Rollback is available, we may get a callback into #onExecuteHealthCheckMitigation
                 impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_30;
             } else if (anyRollbackAvailable) {
                 // If any rollbacks are available, we will commit them
@@ -165,7 +171,7 @@
     }
 
     @Override
-    public boolean execute(@Nullable VersionedPackage failedPackage,
+    public boolean onExecuteHealthCheckMitigation(@Nullable VersionedPackage failedPackage,
             @FailureReasons int rollbackReason, int mitigationCount) {
         Slog.i(TAG, "Executing remediation."
                 + " failedPackage: "
@@ -219,7 +225,7 @@
     }
 
     @Override
-    public boolean executeBootLoopMitigation(int mitigationCount) {
+    public boolean onExecuteBootLoopMitigation(int mitigationCount) {
         if (Flags.recoverabilityDetection()) {
             List<RollbackInfo> availableRollbacks = getAvailableRollbacks();
 
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index bfc00bb..b48c55d 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -329,18 +329,6 @@
         disconnectFromRemoteDocument();
     }
 
-    public void kill(String reason) {
-        if (DEBUG) {
-            Log.i(LOG_TAG, "[CALLED] kill()");
-        }
-
-        try {
-            mPrintDocumentAdapter.kill(reason);
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error calling kill()", re);
-        }
-    }
-
     public boolean isUpdating() {
         return mState == STATE_UPDATING || mState == STATE_CANCELING;
     }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index c4173ed..bd2b5ec 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -514,8 +514,12 @@
         ensureErrorUiShown(null, PrintErrorFragment.ACTION_RETRY);
 
         setState(STATE_UPDATE_FAILED);
-
-        mPrintedDocument.kill(message);
+        if (DEBUG) {
+            Log.i(LOG_TAG, "PrintJob state[" +  PrintJobInfo.STATE_FAILED + "] reason: " + message);
+        }
+        PrintSpoolerService spooler = mSpoolerProvider.getSpooler();
+        spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_FAILED, message);
+        mPrintedDocument.finish();
     }
 
     @Override
diff --git a/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg.xml b/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg.xml
deleted file mode 100644
index 35517ea..0000000
--- a/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ 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.
-  -->
-
-<shape
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    android:shape="rectangle">
-    <solid android:color="?androidprv:attr/colorAccentPrimary" />
-    <corners android:radius="12dp" />
-</shape>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg_ripple.xml b/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg_ripple.xml
index 18696c6..91a95a5 100644
--- a/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg_ripple.xml
+++ b/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg_ripple.xml
@@ -16,6 +16,12 @@
   -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:color="?android:attr/colorControlHighlight">
-    <item android:drawable="@drawable/audio_sharing_rounded_bg"/>
+    <item>
+        <shape android:shape="rectangle">
+            <corners android:radius="4dp" />
+            <solid android:color="?androidprv:attr/colorAccentPrimary" />
+        </shape>
+    </item>
 </ripple>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg_ripple_bottom.xml b/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg_ripple_bottom.xml
new file mode 100644
index 0000000..cce8a75
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg_ripple_bottom.xml
@@ -0,0 +1,31 @@
+<?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.
+  -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:color="?android:attr/colorControlHighlight">
+    <item>
+        <shape android:shape="rectangle">
+            <corners
+                android:bottomLeftRadius="12dp"
+                android:bottomRightRadius="12dp"
+                android:topLeftRadius="4dp"
+                android:topRightRadius="4dp" />
+            <solid android:color="?androidprv:attr/colorAccentPrimary" />
+        </shape>
+    </item>
+</ripple>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg_ripple_top.xml b/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg_ripple_top.xml
new file mode 100644
index 0000000..1404197
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/audio_sharing_rounded_bg_ripple_top.xml
@@ -0,0 +1,31 @@
+<?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.
+  -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:color="?android:attr/colorControlHighlight">
+    <item>
+        <shape android:shape="rectangle">
+            <corners
+                android:bottomLeftRadius="4dp"
+                android:bottomRightRadius="4dp"
+                android:topLeftRadius="12dp"
+                android:topRightRadius="12dp" />
+            <solid android:color="?androidprv:attr/colorAccentPrimary" />
+        </shape>
+    </item>
+</ripple>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 2f158c8..79c3799 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Aktiveer die Verbeterde Konnektiwiteit-kenmerk."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Plaaslike terminaal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Aktiveer terminaalprogram wat plaaslike skermtoegang bied"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-ontwikkelingomgewing"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Laat loop Linux-terminaal op Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontrolering"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Stel HDCP-kontrolering se gedrag"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Ontfouting"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Geaktiveer"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Jou toestel moet herselflaai om hierdie verandering toe te pas. Herselflaai nou of kanselleer."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Bedrade oorfoon"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Bedrade oudio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-oudio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Bedrade mikrofoon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-mikrofoon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT-mikrofoon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Aan"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 1040f37..5cde078 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"የተሻሻለ ተገናኝነት ባህሪውን ያነቃል።"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"አካባቢያዊ ተርሚናል"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"የአካባቢያዊ ሼል መዳረሻ የሚያቀርብ የተርሚናል መተግበሪያ አንቃ"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"የLinux ግንባታ አከባቢ"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android ላይ Linux ተርሚናል ያሂዱ"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"የHDCP ምልከታ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"የHDCP መመልከቻ ጠባይ አዘጋጅ"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ስህተት በማስወገድ ላይ"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ነቅቷል"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"የእርስዎን መሣሪያ ይህ ለው ለማመልከት እንደገና መነሣት አለበት። አሁን እንደገና ያስነሡ ወይም ይተዉት።"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"ባለገመድ የራስ ላይ ማዳመጫ"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"ግራ የሚያጋባ ኦዶዮ"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB ኦዲዮ"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"ባለገመድ ማይክሮፎን"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB ማይክሮፎን"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"ብሉቱዝ ማይክሮፎን"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"አብራ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 9e1db5f..09bfd83 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"لتفعيل الميزة \"إمكانية اتصال محسّن\""</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"تطبيق طرفي محلي"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"تفعيل تطبيق طرفي يوفر إمكانية الدخول إلى واجهة النظام المحلية"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"‏بيئة تطوير نظام التشغيل Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"‏تشغيل محطة Linux الطرفية على Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"‏التحقق من HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏تعيين سلوك التحقق من HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"تصحيح الأخطاء"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"مفعّل"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"يجب إعادة تشغيل جهازك ليتم تطبيق هذا التغيير. يمكنك إعادة التشغيل الآن أو إلغاء التغيير."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"سماعات رأس سلكية"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"سمّاعة رأس سلكية"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"‏مكبر صوت USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"ميكروفون سلكي"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"‏ميكروفون USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"ميكروفون يعمل بالبلوتوث"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"مفعّلة"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 76a3936..83cd2fe 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -357,6 +357,10 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"উন্নত সংযোগ সুবিধাটো সক্ষম কৰে।"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"স্থানীয় টাৰ্মিনেল"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"স্থানীয় শ্বেলৰ এক্সেছ দিয়া টাৰ্মিনেল এপ্ সক্ষম কৰক"</string>
+    <!-- no translation found for enable_linux_terminal_title (5076044866895670637) -->
+    <skip />
+    <!-- no translation found for enable_linux_terminal_summary (5893216510985145320) -->
+    <skip />
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP পৰীক্ষণ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP পৰীক্ষণ আচৰণ ছেট কৰক"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ডিবাগিং"</string>
@@ -686,11 +690,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"সক্ষম কৰা আছে"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"এই সলনিটো কার্যকৰী হ’বলৈ আপোনাৰ ডিভাইচটো ৰিবুট কৰিবই লাগিব। এতিয়াই ৰিবুট কৰক অথবা বাতিল কৰক।"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"তাঁৰযুক্ত হেডফ’ন"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"তাঁৰযুক্ত অডিঅ’"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"ইউএছবি অডিঅ\'"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"তাঁৰযুক্ত মাইক্ৰ’ফ’ন"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"ইউএছবি মাইক্ৰ’ফ’ন"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"ব্লুটুথ মাইক্ৰ’ফ’ন"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"অন"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 2d9e1d9..459cfaa 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Qabaqcıl məlumat mübadiləsini aktiv edir."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Yerli terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Yerli örtük girişini təklif edən terminal tətbiqi aktiv edin"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux inkişaf mühiti"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android-də Linux terminalını işə salın"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP yoxlanışı"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP yoxlanışı qaydası ayalansın"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Sazlama"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiv"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bu dəyişikliyin tətbiq edilməsi üçün cihaz yenidən başladılmalıdır. İndi yenidən başladın və ya ləğv edin."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Naqilli qulaqlıq"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Simli audio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Simli mikrofon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth mikrofonu"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Aktiv"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 01f0ff2..f883c93 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Omogućava funkciju Poboljšano povezivanje."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući apl. terminala za pristup lokalnom komandnom okruženju"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux okruženje za programiranje"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Pokrenite Linux terminal na Android-u"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provera"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Podešavanje ponašanja HDCP provere"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Otklanjanje grešaka"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Morate da restartujete uređaj da bi se ova promena primenila. Restartujte ga odmah ili otkažite."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Žičane slušalice"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Žičane slušalice"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Žičani mikrofon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth mikrofon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Uključeno"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index f710b1d..ca07c4d 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Уключае функцыю \"Палепшанае падключэнне\"."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Лакальны тэрмінал"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Уключэнне прыкладання тэрмінала, якое прапануе доступ да лакальнай абалонкі"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Асяроддзе распрацоўкі Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Запусціць тэрмінал Linux на прыладзе Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Праверка HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Усталяваць рэжым праверкі HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Адладка"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Уключана"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Перазагрузіце прыладу, каб прымяніць гэта змяненне. Перазагрузіце ці скасуйце."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Правадныя навушнікі"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Правадныя навушнікі"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Аўдыяпрылада USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Правадны мікрафон"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Мікрафон USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Мікрафон з Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Уключана"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index c5c4c91..7661a31d 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Активира функцията за подобрена свързаност."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Локален терминал"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Актив. на прил. за терминал с достъп до локалния команден ред"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Среда на програмиране на Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Стартиране на терминала на Linux под Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка с HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Проверка с HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Отстраняване на грешки"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Активирано"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"За да бъде приложена тази промяна, устройството ви трябва да бъде рестартирано. Рестартирайте сега или анулирайте."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Слушалки с кабел"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Слушалки с кабел"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Аудиоустройство с USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Микрофон с кабел"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Микрофон с USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Микрофон с Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Включване"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index be6b9be..f71a003c 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -357,6 +357,10 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"কানেক্টিভিটি ফিচার উন্নত করার বিষয়টি চালু করা হয়েছে।"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"স্থানীয় টার্মিনাল"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"স্থানীয় শেল অ্যাক্সেসের প্রস্তাব করে এমন টার্মিনাল অ্যাপ্লিকেশন সক্ষম করুন"</string>
+    <!-- no translation found for enable_linux_terminal_title (5076044866895670637) -->
+    <skip />
+    <!-- no translation found for enable_linux_terminal_summary (5893216510985145320) -->
+    <skip />
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP পরীক্ষণ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP চেক করার আচরণ সেট করুন"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ডিবাগিং"</string>
@@ -686,11 +690,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"চালু করা আছে"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"এই পরিবর্তনটি প্রয়োগ করার জন্য আপনার ডিভাইসটি অবশ্যই রিবুট করতে হবে। এখনই রিবুট করুন বা বাতিল করুন।"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"তারযুক্ত হেডফোন"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"তারযুক্ত অডিও"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB অডিও"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"তারযুক্ত মাইক্রোফোন"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB মাইক্রোফোন"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT মাইক্রোফোন"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"চালু আছে"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index f343430..b76b028 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Omogućava funkciju Poboljšane povezivosti."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući terminalnu aplik. koja nudi pristup lok. kom. okruženju"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linuxovo okruženje za razvoj"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Pokreni Linux terminal na Androidu"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provjera"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Postavke HDCP provjere"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Otklanjanje grešaka"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Morate ponovo pokrenuti uređaj da se ova promjena primijeni. Ponovo pokrenite odmah ili otkažite."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Žičane slušalice"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Žičani audio uređaj"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Žičani mikrofon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT mikrofon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Uključi"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 3557b10..2aa3ffa 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Activa la funció de connectivitat millorada."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Activa l\'aplicació de terminal que ofereix accés al shell local"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Entorn de desenvolupament Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Executa el terminal de Linux a Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Comprovació d\'HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Defineix comprovació HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Depuració"</string>
@@ -611,10 +613,10 @@
     <string name="shared_data_title" msgid="1017034836800864953">"Dades compartides"</string>
     <string name="shared_data_summary" msgid="5516326713822885652">"Mostra i modifica les dades compartides"</string>
     <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"No hi ha dades compartides per a aquest usuari"</string>
-    <string name="shared_data_query_failure_text" msgid="3489828881998773687">"S\'ha produït un error en recollir les dades compartides. Torna-ho a provar."</string>
+    <string name="shared_data_query_failure_text" msgid="3489828881998773687">"Hi ha hagut un error en recollir les dades compartides. Torna-ho a provar."</string>
     <string name="blob_id_text" msgid="8680078988996308061">"Identificador de dades compartides: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
     <string name="blob_expires_text" msgid="7882727111491739331">"Caduquen el dia <xliff:g id="DATE">%s</xliff:g>"</string>
-    <string name="shared_data_delete_failure_text" msgid="3842701391009628947">"S\'ha produït un error en suprimir les dades compartides."</string>
+    <string name="shared_data_delete_failure_text" msgid="3842701391009628947">"Hi ha hagut un error en suprimir les dades compartides."</string>
     <string name="shared_data_no_accessors_dialog_text" msgid="8903738462570715315">"No s\'ha adquirit cap arrendament d\'aquestes dades. Vols suprimir-les?"</string>
     <string name="accessor_info_title" msgid="8289823651512477787">"Aplicacions que comparteixen dades"</string>
     <string name="accessor_no_description_text" msgid="7510967452505591456">"L\'aplicació no ha proporcionat cap descripció."</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activat"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Has de reiniciar el teu dispositiu perquè s\'apliquin els canvis. Reinicia\'l ara o cancel·la."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Auriculars amb cable"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Àudio amb cable"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Àudio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Micròfon amb cable"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Micròfon USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Micròfon Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Activa"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index ae47c46..0a88338 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Aktivuje funkci Lepší připojování."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Místní terminál"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivovat terminálovou aplikaci pro místní přístup k prostředí shell"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Vývojové prostředí Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Spustit na Androidu terminál Linux"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Kontrola HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Nastavit chování kontroly HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Ladění"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Zapnuto"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Aby se tato změna projevila, je třeba zařízení restartovat. Restartujte zařízení nebo zrušte akci."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Kabelová sluchátka"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Zvuk přes kabel"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Zvuk USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Kabelový mikrofon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Mikrofon USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Mikrofon Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Zapnout"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 82d7021..983003b 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Aktivér funktionen Enhanced Connectivity."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Lokal terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivér terminalappen, der giver lokal shell-adgang"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-udviklingsmiljø"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Kør Linux-terminal i Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontrol"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Angiv HDCP-kontroladfærd"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Fejlretning"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiveret"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Din enhed skal genstartes for at anvende denne ændring. Genstart nu, eller annuller."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Høretelefoner med ledning"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Lyd med ledning"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-lydenhed"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Mikrofon med ledning"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT-mikrofon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Til"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 00ae7e4..1a5e15a 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -357,6 +357,10 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Aktiviert die Funktion \"Verbesserte Konnektivität\"."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Lokales Terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Terminal-App mit Zugriff auf lokale Shell aktivieren"</string>
+    <!-- no translation found for enable_linux_terminal_title (5076044866895670637) -->
+    <skip />
+    <!-- no translation found for enable_linux_terminal_summary (5893216510985145320) -->
+    <skip />
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-Prüfung"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP-Prüfverhalten festlegen"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string>
@@ -686,11 +690,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiviert"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Damit diese Änderung übernommen wird, musst du dein Gerät neu starten. Du kannst es jetzt neu starten oder den Vorgang abbrechen."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Kabelgebundene Kopfhörer"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Kabelgebundene Kopfhörer"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-Audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Kabelgebundenes Mikrofon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-Mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth-Mikrofon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"An"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 7dbe274..c838f68 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Επιτρέπει τη λειτουργία Βελτιωμένης συνδεσιμότητας."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Τοπική τερματική εφαρμογή"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Ενεργοπ.τερμ.εφαρμογής που προσφέρει πρόσβαση στο τοπικό κέλυφος"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Περιβάλλον ανάπτυξης Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Εκτέλεση τερματικού Linux σε Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Έλεγχος HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Ρύθμιση συμπεριφοράς ελέγχου HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Εντοπισμός σφαλμάτων"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ενεργή"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Για να εφαρμοστεί αυτή η αλλαγή, θα πρέπει να επανεκκινήσετε τη συσκευή σας. Επανεκκίνηση τώρα ή ακύρωση."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Ενσύρματα ακουστικά"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Ενσύρματος ήχος"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Ήχος USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Ενσύρματο μικρόφωνο"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Μικρόφωνο USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Μικρόφωνο BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Ενεργό"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index f29a02b..b4bf205 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Enables the enhanced connectivity feature."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux development environment"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Run Linux terminal on Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Set HDCP checking behaviour"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Wired headphones"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Wired audio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Wired microphone"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB microphone"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT microphone"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"On"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 81489fe..af392b83 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Enables the Enhanced Connectivity feature."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux development environment"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Run Linux terminal on Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Set HDCP checking behavior"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index f29a02b..b4bf205 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Enables the enhanced connectivity feature."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux development environment"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Run Linux terminal on Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Set HDCP checking behaviour"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Wired headphones"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Wired audio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Wired microphone"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB microphone"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT microphone"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"On"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index f29a02b..b4bf205 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Enables the enhanced connectivity feature."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux development environment"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Run Linux terminal on Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Set HDCP checking behaviour"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Wired headphones"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Wired audio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Wired microphone"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB microphone"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT microphone"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"On"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 07b8d88..3c1a278 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Habilita la función Conectividad mejorada."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Habilitar aplicac. de terminal que ofrece acceso al shell local"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Entorno de desarrollo de Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Ejecuta la terminal de Linux en Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Comprobación HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Configurar comportamiento de la comprobación HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Depuración"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Habilitado"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Debes reiniciar el dispositivo para que se aplique el cambio. Reinícialo ahora o cancela la acción."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Auriculares con cable"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Auriculares con cable"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Audio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Micrófono con cable"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Micrófono USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Micrófono Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Activar"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 56355b1..94502c5 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Habilita la función de conectividad mejorada."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Habilitar aplicación de terminal que ofrece acceso a shell local"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Entorno de desarrollo de Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Ejecuta un terminal de Linux en Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Comprobación de HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Establecer comprobación HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Depuración"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Habilitado"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Es necesario reiniciar tu dispositivo para que se apliquen los cambios. Reinicia ahora o cancela la acción."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Auriculares con cable"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Audio con cable"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Audio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Micrófono con cable"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Micrófono USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Micrófono Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Activado"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 6582864..5f5a38c 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Lubab täiustatud ühenduvuse funktsiooni."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Kohalik terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Luba kohalikku turvalist juurdepääsu pakkuv terminalirakendus"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linuxi arenduskeskkond"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Linuxi terminali käitamine Androidis"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontrollimine"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP käitumise määramine"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Silumine"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Lubatud"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Selle muudatuse rakendamiseks tuleb seade taaskäivitada. Taaskäivitage kohe või tühistage."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Juhtmega kõrvaklapid"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Juhtmega heli"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-heli"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Juhtmega mikrofon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT mikrofon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Sees"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index f9ec6f7..2c512b7 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Konexioak hobetzeko eginbidea gaitzen du."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Tokiko terminala"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Gaitu tokiko shell-sarbidea duen terminal-aplikazioa"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-eko garapen-ingurunea"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Exekutatu Linux-en terminala Android-en"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP egiaztapena"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Ezarri HDCP egiaztapen-portaera"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Arazketa"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Gaituta"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Aldaketa aplikatzeko, berrabiarazi egin behar da gailua. Berrabiaraz ezazu orain, edo utzi bertan behera."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Entzungailu kableduna"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Audio kableduna"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB bidezko audioa"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Mikrofono kableduna"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB bidezko mikrofonoa"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth bidezko mikrofonoa"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Aktibatu"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 9c704c5..1aeca86 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"ویژگی «اتصال بهبودیافته» را فعال می‌کند."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"ترمینال محلی"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"فعال کردن ترمینال برنامه‌ کاربردی که دسترسی به برنامه محلی را پیشنهاد می‌کند"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"‏محیط توسعه نرم‌افزار Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"‏اجرا کردن پایانه Linux در Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"‏بررسی HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏تنظیم عملکرد بررسی HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"اشکال‌زدایی"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"فعال"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"برای اعمال این تغییر، دستگاه باید بازراه‌اندازی شود. یا اکنون بازراه‌اندازی کنید یا لغو کنید."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"هدفون سیمی"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"صدای سیمی"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"‏بلندگوی USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"میکروفون سیمی"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"‏میکروفون USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"میکروفون بلوتوث"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"روشن"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 193ec70..53724a3 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Ottaa käyttöön Parannetut yhteydet ‑ominaisuuden."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Paikallinen pääte"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Ota käyttöön päätesov. joka mahdollistaa paikall. liittymäkäytön"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-kehitysympäristö"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Käynnistä Linux-pääte Androidilla"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-tarkistus"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Aseta HDCP-tarkistus"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Vianetsintä"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Käytössä"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Laitteesi on käynnistettävä uudelleen, jotta muutos tulee voimaan. Käynnistä uudelleen nyt tai peru."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Langalliset kuulokkeet"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Langallinen audio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Langallinen mikrofoni"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-mikrofoni"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT-mikrofoni"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Päällä"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index b527990..30eba9e 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Active la fonctionnalité Connectivité améliorée."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Activer l\'appli Terminal permettant l\'accès au shell local"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Environnement de développement Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Exécuter le terminal Linux sur Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Vérification HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Configurer vérification HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Débogage"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activé"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Votre appareil doit être redémarré pour que ce changement prenne effet. Redémarrez-le maintenant ou annulez la modification."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Écouteurs filaires"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Audio filaire"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Audio par USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Microphone filaire"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Microphone USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Microphone BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Activé"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index fb2bcf3..f4afc87 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Active la fonctionnalité Connectivité améliorée."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Activer l\'application Terminal permettant l\'accès au shell local"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Environnement de développement Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Exécuter le terminal Linux sur Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Vérification HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Config. vérification HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Débogage"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activé"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Vous devez redémarrer l\'appareil pour que cette modification soit appliquée. Redémarrez maintenant ou annulez l\'opération."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Casque filaire"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Audio filaire"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Audio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Micro filaire"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Micro USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Micro Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Allumé"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index d6e9f3f..be1fac8 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Activa a función de conectividade mellorada"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Activa a aplicación terminal que ofrece acceso ao shell local"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Contorno de programación Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Executar terminal de Linux en Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Comprobación HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Definir comprobación HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Depuración"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activado"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necesario reiniciar o teu dispositivo para aplicar este cambio. Reiníciao agora ou cancela o cambio."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Auriculares con cable"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Audio con cable"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Audio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Micrófono con cable"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Micrófono USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Micrófono Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Activada"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index b804dd4..f343ff4 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -357,6 +357,10 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"કનેક્ટિવિટીની વિસ્તૃત સુવિધા ચાલુ કરે છે."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"સ્થાનિક ટર્મિનલ"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"સ્થાનિક શેલ અ‍ૅક્સેસની ઑફર કરતી ટર્મિનલ એપ્લિકેશનને સક્ષમ કરો"</string>
+    <!-- no translation found for enable_linux_terminal_title (5076044866895670637) -->
+    <skip />
+    <!-- no translation found for enable_linux_terminal_summary (5893216510985145320) -->
+    <skip />
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP તપાસણી"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP તપાસણીની વર્તણૂક બદલો"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ડીબગિંગ"</string>
@@ -686,11 +690,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ચાલુ છે"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"આ ફેરફારને લાગુ કરવા માટે તમારા ડિવાઇસને રીબૂટ કરવાની જરૂર છે. હમણાં જ રીબૂટ કરો કે રદ કરો."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"વાયરવાળો હૅડફોન"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"વાયર્ડ ઑડિયો"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB ઑડિયો"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"વાયર્ડ માઇક્રોફોન"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB માઇક્રોફોન"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT માઇક્રોફોન"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ચાલુ"</string>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index 7a22465..2173ad6 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -216,7 +216,7 @@
   <string-array name="transition_animation_scale_entries">
     <item msgid="3376676813923486384">"एनिमेशन बंद"</item>
     <item msgid="753422683600269114">"एनिमेशन स्‍केल .5x"</item>
-    <item msgid="3695427132155563489">"ऐनिमेशन स्‍केल 1x"</item>
+    <item msgid="3695427132155563489">"ऐनिमेशन स्‍केल 1 गुना"</item>
     <item msgid="9032615844198098981">"एनिमेशन स्‍केल 1.5x"</item>
     <item msgid="8473868962499332073">"एनिमेशन स्‍केल 2x"</item>
     <item msgid="4403482320438668316">"एनिमेशन स्‍केल 5x"</item>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 7c5e66c..352dba7 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"कनेक्टिविटी बेहतर बनाने की सुविधा को चालू करें"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"स्थानीय टर्मिनल"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"लोकल शेल तक पहुंचने की सुविधा देने वाले टर्मिनल ऐप को चालू करें"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux डेवलपमेंट एनवायरमेंट"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android पर Linux का टर्मिनल ऐप्लिकेशन चलाएं"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP जांच"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP जाँच व्‍यवहार सेट करें"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"डीबग करना"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"चालू है"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"बदली गई सेटिंग को लागू करने के लिए, डिवाइस को रीस्टार्ट करना होगा. अपने डिवाइस को रीस्टार्ट करें या रद्द करें."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"तार वाला हेडफ़ोन"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"तार वाला हेडफ़ोन"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"यूएसबी ऑडियो"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"तार वाला माइक्रोफ़ोन"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"यूएसबी माइक्रोफ़ोन"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"ब्लूटूथ माइक्रोफ़ोन"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"चालू है"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index fc474dd..0df2a7a 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Omogućuje značajku Poboljšana povezivost."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući aplikaciju terminala koja nudi pristup lokalnoj ovojnici"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linuxovo razvojno okruženje"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Pokrenite Linux terminal na Androidu"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provjera"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Postavke HDCP provjere"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Otklanjanje pogrešaka"</string>
@@ -418,7 +420,7 @@
     <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Omogućeno na neograničeno vrijeme"</string>
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Brzina animacije prozora"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Brzina animacije prijelaza"</string>
-    <string name="animator_duration_scale_title" msgid="7082913931326085176">"Razmjer duljine animatora"</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="debug_applications_category" msgid="5394089406638954196">"Aplikacije"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ukloni aktivnosti"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Uređaj se mora ponovno pokrenuti da bi se ta promjena primijenila. Ponovo pokrenite uređaj odmah ili odustanite."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Žičane slušalice"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Žičane slušalice"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB zvučnik"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Žičani mikrofon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT mikrofon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Uključeno"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 95b2892..86a959a 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Bekapcsolja az Enhanced Connectivity funkciót."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Helyi végpont"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Végalkalmazás engedélyezése a helyi rendszerhéj eléréséhez"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux fejlesztői környezet"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Linux-terminál futtatása Androidon"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-ellenőrzés"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP-ellenőrzés beállítása"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Hibakeresés"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Engedélyezve"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Az eszközt újra kell indítani, hogy a módosítás megtörténjen. Indítsa újra most, vagy vesse el a módosítást."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Vezetékes fejhallgató"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Vezetékes audio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-hangeszköz"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Vezetékes mikrofon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT-mikrofon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Be"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 51190f3..4c29740 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Միացնում է «Տվյալների լավացված փոխանակում» գործառույթը։"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Տեղային տերմինալ"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Միացնել տերմինալային հավելվածը, որն առաջարկում է մուտք տեղային խեցի"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Լինուքսի մշակման միջավայր"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Գործարկել Լինուքս տերմինալը Android-ում"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ստուգում"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP-ի ստուգման կարգը"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Վրիպազերծում"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Միացված է"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Սարքն անհրաժեշտ է վերագործարկել, որպեսզի փոփոխությունը կիրառվի։ Վերագործարկեք հիմա կամ չեղարկեք փոփոխությունը։"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Լարով ականջակալ"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Լարով միացվող աուդիո սարք"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB աուդիո"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Լարով միացվող խոսափող"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB խոսափող"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth խոսափող"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Միացնել"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 84280cf..3b265f8 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Mengaktifkan fitur Konektivitas Yang Disempurnakan."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal lokal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Aktifkan aplikasi terminal yang menawarkan akses kerangka lokal"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Lingkungan pengembangan Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Jalankan terminal Linux di Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Pemeriksaan HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Setel perilaku pemeriksaan HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Proses debug"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktif"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Perangkat Anda harus di-reboot agar perubahan ini diterapkan. Reboot sekarang atau batalkan."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Headphone berkabel"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Audio berkabel"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Audio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Mikrofon berkabel"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Mikrofon USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Mikrofon BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Aktif"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index daadae6..d0184e1 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Virkjar eiginleika aukinnar tengigetu."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Staðbundin skipanalína"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Virkja skipanalínuforrit sem leyfir staðbundinn skeljaraðgang"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Þróunarumhverfi Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Keyra Linux-útstöð í Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-athugun"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Velja virkni HDCP-ath."</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Villuleit"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Virkt"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Endurræsa þarf tækið til að þessi breyting taki gildi. Endurræstu núna eða hættu við."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Heyrnartól með snúru"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Heyrnartól með snúru"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-hljóð"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Hljóðnemi með snúru"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-hljóðnemi"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT-hljóðnemi"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Kveikt"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 36aa2b3..773aa26 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Consente di attivare la funzionalità Connettività migliorata."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminale locale"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Abilita l\'app Terminale che offre l\'accesso alla shell locale"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Ambiente di sviluppo Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Esegui il terminale Linux su Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Verifica HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Comportamento di verifica HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Debug"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Attivo"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Per applicare questa modifica, devi riavviare il dispositivo. Riavvia ora o annulla."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Cuffie con cavo"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Audio con cavo"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Audio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Microfono con cavo"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Microfono USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Microfono BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"On"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 942b99b..45c41dd 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"הפעלה של תכונת הקישוריות המשופרת."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"מסוף מקומי"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"הפעלה של אפליקציית מסוף המציעה גישה מקומית למעטפת"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"‏סביבת פיתוח של Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"‏הפעלת טרמינל Linux ב-Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"‏בדיקת HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏הגדרת האופן של בדיקת HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ניפוי באגים"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"מופעל"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"צריך להפעיל מחדש את המכשיר כדי להחיל את השינוי. יש להפעיל מחדש עכשיו או לבטל."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"אוזניות חוטיות"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"אודיו עם חיבור קווי"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"‏אודיו ב-USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"מיקרופון עם חיבור קווי"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"‏מיקרופון ב-USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"‏מיקרופון BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"פועלת"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 5924ab2..ae3f197 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"接続強化機能を有効にします。"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"ローカルターミナル"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"ローカルシェルアクセスを提供するターミナルアプリを有効にします"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux 開発環境"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android で Linux ターミナルを実行する"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP チェック"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP チェック動作を設定"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"デバッグ"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"有効"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"この変更を適用するには、デバイスの再起動が必要です。今すぐ再起動するか、キャンセルしてください。"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"有線ヘッドフォン"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"有線オーディオ"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB オーディオ"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"有線マイク"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB マイク"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT マイク"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ON"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 5f3d54f..fe9dbb5 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"ჩართავს კავშირის გაძლიერებული შესაძლებლობის ფუნქციას."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"ადგილობრივი ტერმინალი"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"ლოკალურ გარსზე წვდომის ტერმინალური აპლიკაციის ჩართვა"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-ის შემუშავების გარემო"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Linux ტერმინალის გაშვება Android-ზე"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP შემოწმება"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"დააყენე HDCP შემოწმების ქცევა"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"გამართვა"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ჩართული"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ამ ცვლილების ასამოქმედებლად თქვენი მოწყობილობა უნდა გადაიტვირთოს. გადატვირთეთ ახლავე ან გააუქმეთ."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"სადენიანი ყურსასმენი"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"სადენიანი აუდიო"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB აუდიო"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"სადენიანი მიკროფონი"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB მიკროფონი"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT მიკროფონი"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ჩართვა"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index bb6e353..1162e8f 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Жетілдірілген байланыс функциясын қосады."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Жергілікті терминал"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Жергілікті шелл-код қол жетімділігін ұсынатын терминалды қолданбаны қосу"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux әзірлеуші ортасы"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android-та Linux терминалын іске қосыңыз."</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP тексерісі"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP (кең жолақты цифрлық контент қорғау) тексеру мүмкіндігін орнату"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Түзету"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Қосулы"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Бұл өзгеріс күшіне енуі үшін, құрылғыны қайта жүктеу керек. Қазір қайта жүктеңіз не бас тартыңыз."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Сымды құлақаспап"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Сымды аудио"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB аудио"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Сымды микрофон"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB микрофон"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth микрофоны"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Қосу"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 20ed723..5a184c5 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"បើក​មុខងារ​ការតភ្ជាប់​ដែលបានធ្វើឱ្យប្រសើរឡើង។"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"ស្ថានីយ​មូលដ្ឋាន"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"បើក​កម្មវិធី​ស្ថានីយ​ដែល​ផ្ដល់​ការ​ចូល​សែល​មូលដ្ឋាន"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"មជ្ឈដ្ឋាន​អភិវឌ្ឍន៍ Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"ដំណើរការទែមីណាល់ Linux នៅលើ Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"ពិនិត្យ HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"កំណត់​ឥរិយាបថ​ពិនិត្យ HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ការជួសជុល"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"បានបើក"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ត្រូវតែ​ចាប់ផ្ដើម​ឧបករណ៍​របស់អ្នក​ឡើងវិញ ដើម្បីឱ្យ​ការផ្លាស់ប្ដូរ​នេះ​មានប្រសិទ្ធភាព។ ចាប់ផ្ដើមឡើងវិញ​ឥឡូវនេះ ឬ​បោះបង់​។"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"កាស​មានខ្សែ"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"សំឡេងប្រើខ្សែ"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"ឧបករណ៍បំពងសំឡេង USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"មីក្រូហ្វូនប្រើខ្សែ"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"មីក្រូហ្វូន USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"មីក្រូហ្វូន BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"បើក"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 50a1234..f34a43c 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"ವರ್ಧಿತ ಸಂಪರ್ಕ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"ಸ್ಥಳೀಯ ಟರ್ಮಿನಲ್"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"ಸ್ಥಳೀಯ ಶೆಲ್ ಪ್ರವೇಶವನ್ನು ಒದಗಿಸುವ ಟರ್ಮಿನಲ್ ಆ್ಯಪ್‌ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux ಡೆವಲಪ್‌ಮೆಂಟ್ ಎನ್ವಿರಾನ್‌ಮೆಂಟ್"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android ನಲ್ಲಿ Linux ಟರ್ಮಿನಲ್ ಅನ್ನು ರನ್ ಮಾಡಿ"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ಪರೀಕ್ಷಿಸುವಿಕೆ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP ಪರಿಶೀಲನಾ ನಡವಳಿಕೆಯನ್ನು ಹೊಂದಿಸಿ"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ಈ ಬದಲಾವಣೆ ಅನ್ವಯವಾಗಲು ನಿಮ್ಮ ಸಾಧನವನ್ನು ರೀಬೂಟ್ ಮಾಡಬೇಕು. ಇದೀಗ ರೀಬೂಟ್ ಮಾಡಿ ಅಥವಾ ರದ್ದುಗೊಳಿಸಿ."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"ವೈಯರ್ ಹೊಂದಿರುವ ಹೆಡ್‌ಫೋನ್"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"ವೈರ್ ಸಂಪರ್ಕ ಹೊಂದಿರುವ ಆಡಿಯೋ"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB ಆಡಿಯೋ"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"ವೈರ್‌ ಸಂಪರ್ಕ ಹೊಂದಿರುವ ಮೈಕ್ರೋಫೋನ್"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB ಮೈಕ್ರೊಫೋನ್‌"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT ಮೈಕ್ರೊಫೋನ್"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ಆನ್ ಆಗಿದೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index f9949ce..d803404 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"향상된 연결 기능을 사용 설정합니다."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"로컬 터미널"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"로컬 셸 액세스를 제공하는 터미널 앱 사용"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux 개발 환경"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android에서 Linux 터미널 실행"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 확인"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP 확인 동작 설정"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"디버깅"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"사용 설정됨"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"변경사항을 적용하려면 기기를 재부팅해야 합니다. 지금 재부팅하거나 취소하세요."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"유선 헤드폰"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"유선 오디오"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB 오디오"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"유선 마이크"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB 마이크"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"블루투스 마이크"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"사용"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 40bbb35..2fb036f 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Жакшыртылган туташуу функциясын иштетет."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Жергиликтүү терминал"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Жергиликтүү буйрук кабыгын сунуштаган терминалга уруксат берүү"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux иштеп чыгуу чөйрөсү"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android\'де Linux терминалын иштетүү"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP текшерүү"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP текшерүү тартиби"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Мүчүлүштүктөрдү аныктоо"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Күйүк"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Бул өзгөрүү күчүнө кириши үчүн, түзмөктү өчүрүп күйгүзүңүз. Азыр же кийинчерээк өчүрүп күйгүзсөңүз болот."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Зымдуу гарнитура"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Зымдуу аудио түзмөк"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB аудио"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Зымдуу микрофон"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB микрофон"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth микрофону"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Күйгүзүү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index b5f8922..da631b6 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -357,6 +357,10 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"ເປີດນຳໃຊ້ຄຸນສົມບັດການເຊື່ອມຕໍ່ທີ່ເສີມແຕ່ງແລ້ວ"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal ໃນໂຕເຄື່ອງ"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"ເປີດນຳໃຊ້ແອັບຯ Terminal ທີ່ໃຫ້ການເຂົ້າເຖິງ shell ໃນໂຕເຄື່ອງໄດ້"</string>
+    <!-- no translation found for enable_linux_terminal_title (5076044866895670637) -->
+    <skip />
+    <!-- no translation found for enable_linux_terminal_summary (5893216510985145320) -->
+    <skip />
     <string name="hdcp_checking_title" msgid="3155692785074095986">"ການກວດສອບ HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"ຕັ້ງວິທີການກວດສອບ HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ການດີບັກ"</string>
@@ -686,11 +690,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ເປີດການນຳໃຊ້ແລ້ວ"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ທ່ານຕ້ອງປິດເປີດອຸປະກອນຄືນໃໝ່ເພື່ອນຳໃຊ້ການປ່ຽນແປງນີ້. ປິດເປີດໃໝ່ດຽວນີ້ ຫຼື ຍົກເລີກ."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"ຫູຟັງແບບມີສາຍ"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"ສຽງແບບມີສາຍ"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"ສຽງ USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"ໄມໂຄຣໂຟນແບບມີສາຍ"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"ໄມໂຄຣໂຟນ USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"ໄມໂຄຣໂຟນ BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ເປີດ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index fd23ece..0c235b8 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Įgalinti patobulinto ryšio funkciją."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Vietinis terminalas"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Įgal. terminalo progr., siūlančią prieigą prie viet. apvalkalo"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"„Linux“ kūrimo aplinka"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"„Linux“ terminalo paleidimas sistemoje „Android“"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP tikrinimas"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Nust. HDCP tikrin. elgs."</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Derinimas"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Įgalinta"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Kad pakeitimas būtų pritaikytas, įrenginį reikia paleisti iš naujo. Dabar paleiskite iš naujo arba atšaukite."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Laidinės ausinės"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Laidinis garso įrenginys"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB garsas"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Laidinis mikrofonas"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB mikrofonas"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"„Bluetooth“ mikrofonas"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Įjungta"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 4fbbbe9..daaebc8 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Tiek iespējota uzlabotās savienojamības funkcija."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Vietējā beigu lietotne"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Iespējot beigu lietotni, kurā piedāvāta vietējā čaulas piekļuve"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux izstrādes vide"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Palaist Linux termināli Android ierīcē"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP pārbaude"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP pārb. iestatīšana"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Atkļūdošana"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Iespējots"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Lai šīs izmaiņas tiktu piemērotas, nepieciešama ierīces atkārtota palaišana. Atkārtoti palaidiet to tūlīt vai atceliet izmaiņas."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Vadu austiņas"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Vadu audio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Vadu mikrofons"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB mikrofons"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth mikrofons"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Ieslēgts"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index ea53b93..f5e84a2 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Ја овозможува функцијата „Подобрена поврзливост“."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Локален терминал"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Овозможи апликација на терминал што овозможува локален пристап кон школка."</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Програмерска околина на Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Извршување Linux-терминал на Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка со HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Постави однесување на проверка на HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Отстранување грешки"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Овозможено"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"За да се примени променава, уредот мора да се рестартира. Рестартирајте сега или откажете."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Жичени слушалки"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Жичени слушалки"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-аудио"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Жичен микрофон"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-микрофон"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Микрофон со Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Вклучено"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 43ac862..7dd2073 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"മെച്ചപ്പെടുത്തിയ കണക്റ്റിവിറ്റി ഫീച്ചർ പ്രവർത്തനക്ഷമമാക്കുന്നു."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"പ്രാദേശിക ടെർമിനൽ"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"പ്രാദേശിക ഷെൽ ആക്‌സസ് നൽകുന്ന ടെർമിനൽ അപ്ലിക്കേഷൻ പ്രവർത്തനക്ഷമമാക്കുക"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux ഡെവലപ്പ്മെന്റ് എൻവയോൺമെന്റ്"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android-ൽ Linux ടെർമിനൽ പ്രവർത്തിപ്പിക്കുക"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP പരിശോധന"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP ചെക്കിംഗ്‌രീതി സജ്ജമാക്കുക"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ഡീബഗ്ഗിംഗ്"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"പ്രവർത്തനക്ഷമമാക്കി"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ഈ മാറ്റം ബാധകമാകുന്നതിന് നിങ്ങളുടെ ഉപകരണം റീബൂട്ട് ചെയ്യേണ്ടതുണ്ട്. ഇപ്പോൾ റീബൂട്ട് ചെയ്യുകയോ റദ്ദാക്കുകയോ ചെയ്യുക."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"വയേർഡ് ഹെഡ്ഫോൺ"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"വയേർഡ് ഓഡിയോ"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB ഓഡിയോ"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"വയേർഡ് മൈക്രോഫോൺ"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB മൈക്രോഫോൺ"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT മൈക്രോഫോൺ"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ഓണാണ്"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index d3b67c7..615edff 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -357,6 +357,10 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Сайжруулсан холболтын онцлогийг идэвхжүүлдэг."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Локал терминал"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Локал суурьт хандалт хийх боломж олгодог терминалын апп-г идэвхжүүлэх"</string>
+    <!-- no translation found for enable_linux_terminal_title (5076044866895670637) -->
+    <skip />
+    <!-- no translation found for enable_linux_terminal_summary (5893216510985145320) -->
+    <skip />
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP шалгах"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP шалгах авирыг тохируулах"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Дебаг"</string>
@@ -686,11 +690,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Идэвхжүүлсэн"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Энэ өөрчлөлтийг хэрэгжүүлэхийн тулд таны төхөөрөмжийг дахин асаах ёстой. Одоо дахин асаах эсвэл цуцлана уу."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Утастай чихэвч"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Утастай аудио"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB аудио"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Утастай микрофон"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB микрофон"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT микрофон"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Асаах"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 9d22c00..be9464c 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"वर्धित कनेक्टिव्हिटी वैशिष्‍ट्य सुरू करा."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"स्थानिक टर्मिनल"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"स्थानिक शेल प्रवेश देणारा टर्मिनल अ‍ॅप सुरू करा"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux विकास पर्यावरण"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android वर Linux टर्मिनल रन करा"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP तपासणी"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP तपासणी वर्तन सेट करा"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"डीबग करणे"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"सुरू केले आहे"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"हा बदल लागू करण्यासाठी तुमचे डिव्हाइस रीबूट करणे आवश्यक आहे. आता रीबूट करा किंवा रद्द करा."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"वायर्ड हेडफोन"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"वायर्ड ऑडिओ"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB ऑडिओ"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"वायर्ड मायक्रोफोन"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB मायक्रोफोन"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT मायक्रोफोन"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"सुरू करा"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 22ff9dd..8f67d33 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Mendayakan ciri Kesambungan Dipertingkat"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal setempat"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Dayakan apl terminal yang menawarkan akses shell tempatan"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Persekitaran pembangunan Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Terminal Run Linux pada Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Penyemakan HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Ttpkn tngkh laku smk HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Menyahpepijat"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Didayakan"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Peranti anda mesti dibut semula supaya perubahan ini berlaku. But semula sekarang atau batalkan."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Fon kepala berwayar"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Audio berwayar"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Audio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Mikrofon berwayar"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Mikrofon USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Mikrofon BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Hidup"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 9a33712..9bb30c7 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"အရည်အသွေးမြှင့်တင်ထားသော ချိတ်ဆက်နိုင်သည့် ဝန်ဆောင်မှုကို ဖွင့်ပါ။"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"လိုကယ်တာမီနယ်"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"local shell အသုံးပြုခွင့်ကမ်းလှမ်းသော တာမင်နယ်အပလီကေးရှင်းဖွင့်ပါ"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux ဆော့ဖ်ဝဲရေးမှု ပတ်ဝန်းကျင်"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android တွင် Linux တာမီနယ် လုပ်ဆောင်ရန်"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP စစ်ဆေးမှု"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP စစ်ဆေးပုံကို သတ်မှတ်မည်"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"အမှားရှာဖွေဖယ်ရှားခြင်း"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ဖွင့်ထားသည်"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ဤအပြောင်းအလဲ ထည့်သွင်းရန် သင့်စက်ကို ပြန်လည်စတင်ရမည်။ ယခု ပြန်လည်စတင်ပါ သို့မဟုတ် ပယ်ဖျက်ပါ။"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"ကြိုးတပ်နားကြပ်"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"ကြိုးသွယ်ထားသည့် အသံ"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB အသံ"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"ကြိုးသွယ်ထားသည့် မိုက်ခရိုဖုန်း"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB မိုက်ခရိုဖုန်း"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT မိုက်ခရိုဖုန်း"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ဖွင့်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 3b03d73..10c0e21 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Slår på Forbedret tilkobling-funksjonen."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Lokal terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Aktiver terminalappen som gir lokal kommandolistetilgang"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-utviklingsmiljø"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Kjør Linux-terminal på Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontroll"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Angi HDPC-kontrolladferd"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Feilsøking"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Slått på"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Enheten din må startes på nytt for at denne endringen skal tre i kraft. Start på nytt nå eller avbryt."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Hodetelefoner med kabel"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Lyd med kabel"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-lyd"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Mikrofon med kabel"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT-mikrofon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"På"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 84c8466..b263761 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"यसले परिष्कृत जडानको सुविधा सक्षम पार्छ।"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"स्थानीय टर्मिनल"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"स्थानीय सेल पहुँच प्रदान गर्ने टर्मिनल एप सक्षम गर्नुहोस्"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux डेभलप्मेन्ट इन्भायरमेन्ट"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android मा Linux टर्मिनल एप प्रयोग गर्नुहोस्"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP जाँच"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP जाँच व्यवहार सेट गर्नुहोस्"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"डिबग गरिँदै छ"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"सक्षम पारिएको छ"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"यो परिवर्तन लागू गर्न तपाईंको यन्त्र अनिवार्य रूपमा रिबुट गर्नु पर्छ। अहिले रिबुट गर्नुहोस् वा रद्द गर्नुहोस्।"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"तारयुक्त हेडफोन"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"तारयुक्त अडियो"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB अडियो"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"तारयुक्त माइक्रोफोन"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB माइक्रोफोन"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT माइक्रोफोन"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"अन छ"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 83df29a..75d5617 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Hiermee wordt de functie voor verbeterde connectiviteit aangezet."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Lokale terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Terminal-app aanzetten die lokale shell-toegang biedt"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-ontwikkelomgeving"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Linux-terminal uitvoeren op Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-controle"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP-controlegedrag instellen"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Foutopsporing"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aan"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Je apparaat moet opnieuw worden opgestart om deze wijziging toe te passen. Start nu opnieuw op of annuleer de wijziging."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Bedrade koptelefoon"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Bedrade audio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Bedrade microfoon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-microfoon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT-microfoon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Aan"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index d03c8f3..fb3a166 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -357,6 +357,10 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"ଏନହାନ୍ସଡ୍ କନେକ୍ଟିଭିଟି ଫିଚର୍ ସକ୍ଷମ କରିଥାଏ।"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"ସ୍ଥାନୀୟ ଟର୍ମିନାଲ୍‌"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"ସ୍ଥାନୀୟ ଶେଲ୍‌କୁ ଆକ‌ସେସ୍‌ ଦେଉଥିବା ଟର୍ମିନଲ୍‌ ଆପ୍‌କୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <!-- no translation found for enable_linux_terminal_title (5076044866895670637) -->
+    <skip />
+    <!-- no translation found for enable_linux_terminal_summary (5893216510985145320) -->
+    <skip />
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ଯାଞ୍ଚ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCPର ଯାଞ୍ଚ ଗତିବିଧି ସେଟ୍‍ କରନ୍ତୁ"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ଡିବଗ୍‌ କରୁଛି"</string>
@@ -686,11 +690,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ସକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ଏହି ପରିବର୍ତ୍ତନ ଲାଗୁ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିଶ୍ଚିତ ରୂପେ ରିବୁଟ୍ କରାଯିବା ଆବଶ୍ୟକ। ବର୍ତ୍ତମାନ ରିବୁଟ୍ କରନ୍ତୁ କିମ୍ବା ବାତିଲ କରନ୍ତୁ।"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"ତାରଯୁକ୍ତ ହେଡଫୋନ"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"ୱାୟାର୍ଡ ଅଡିଓ"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB ଅଡିଓ"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"ୱାୟାର୍ଡ ମାଇକ୍ରୋଫୋନ"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB ମାଇକ୍ରୋଫୋନ"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT ମାଇକ୍ରୋଫୋନ"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ଚାଲୁ ଅଛି"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 1d48207..06a17a3 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -357,6 +357,10 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"ਵਿਸਤ੍ਰਿਤ ਕਨੈਕਟੀਵਿਟੀ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਚਾਲੂ ਕਰਦਾ ਹੈ।"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"ਸਥਾਨਕ ਟਰਮੀਨਲ"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"ਟਰਮੀਨਲ ਐਪ ਨੂੰ ਚਾਲੂ ਕਰੋ ਜੋ ਸਥਾਨਕ ਸ਼ੈਲ ਪਹੁੰਚ ਪੇਸ਼ਕਸ਼ ਕਰਦਾ ਹੈ"</string>
+    <!-- no translation found for enable_linux_terminal_title (5076044866895670637) -->
+    <skip />
+    <!-- no translation found for enable_linux_terminal_summary (5893216510985145320) -->
+    <skip />
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ਜਾਂਚ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP ਜਾਂਚ ਵਿਵਹਾਰ ਸੈੱਟ ਕਰੋ"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ਡੀਬੱਗਿੰਗ"</string>
@@ -686,11 +690,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ਇਸ ਤਬਦੀਲੀ ਨੂੰ ਲਾਗੂ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨੂੰ ਰੀਬੂਟ ਕਰਨਾ ਲਾਜ਼ਮੀ ਹੈ। ਹੁਣੇ ਰੀਬੂਟ ਕਰੋ ਜਾਂ ਰੱਦ ਕਰੋ।"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"ਤਾਰ ਵਾਲੇ ਹੈੱਡਫ਼ੋਨ"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"ਤਾਰ ਵਾਲਾ ਆਡੀਓ ਡੀਵਾਈਸ"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB ਆਡੀਓ"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"ਤਾਰ ਵਾਲਾ ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ਚਾਲੂ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index e8492d3..0a8ea16 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Włącza funkcję lepszej obsługi połączeń."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal lokalny"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Włącz terminal, który umożliwia dostęp do powłoki lokalnej"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Środowisko programistyczne Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Uruchom terminal Linux na Androidzie"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Sprawdzanie HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Ustaw sprawdzanie HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Debugowanie"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 20bd69a..c396488 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Ativa o recurso \"Conectividade melhorada\"."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Ativar o app terminal que oferece acesso ao shell local"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Ambiente de desenvolvimento do Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Executar terminal Linux no Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Verificação HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Config. a verificação HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Depuração"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Fones de ouvido com fio"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Áudio com fio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Áudio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Microfone com fio"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Microfone USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Microfone Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Ativado"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 488dd5a..be91222 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Ativa a funcionalidade Conetividade melhorada."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Ativar aplicação terminal que oferece acesso local à shell"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Ambiente de programação Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Executar terminal do Linux no Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Verificação HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Definir o comportamento da verificação HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Depuração"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativada"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reiniciar o dispositivo para aplicar esta alteração. Reinicie agora ou cancele."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Auscultadores com fios"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Áudio com fios"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Áudio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Microfone com fios"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Microfone USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Microfone BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Ligado"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 20bd69a..c396488 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Ativa o recurso \"Conectividade melhorada\"."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Ativar o app terminal que oferece acesso ao shell local"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Ambiente de desenvolvimento do Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Executar terminal Linux no Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Verificação HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Config. a verificação HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Depuração"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Fones de ouvido com fio"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Áudio com fio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Áudio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Microfone com fio"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Microfone USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Microfone Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Ativado"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index edd0356..4a0023f 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Activează funcția Conectivitate îmbunătățită."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Aplicație terminal locală"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Activează aplicația terminal care oferă acces la shell local"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Mediu de dezvoltare Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Rulează Linux terminal pe Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Verificare HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Configurează verif. HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Depanare"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activat"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Pentru ca modificarea să se aplice, trebuie să repornești dispozitivul. Repornește-l acum sau anulează."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Căști cu fir"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Audio cu fir"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Audio USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Microfon cu fir"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Microfon USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Microfon BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Activat"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 55fbfa5..1abe67a 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Включить улучшенный обмен данными"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Локальный терминальный доступ"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Разрешить терминальный доступ к локальной оболочке"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Среда разработки Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Запустить терминал Linux в Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Порядок проверки HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Отладка"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Включено"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Чтобы изменение вступило в силу, необходимо перезапустить устройство. Вы можете сделать это сейчас или позже."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Проводные наушники"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Проводное аудиоустройство"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-аудиоустройство"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Проводной микрофон"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-микрофон"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth-микрофон"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Вкл."</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index d48824a..2764ed2 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -357,6 +357,10 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"වැඩිදියුණු කළ සබැඳුම් හැකියා විශේෂාංගය සබල කරයි."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"අභ්‍යන්තර අන්තය"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"දේශීය ෂෙල් ප්‍රවේශනය පිරිනමන ටර්මිනල් යෙදුම සබල කරන්න"</string>
+    <!-- no translation found for enable_linux_terminal_title (5076044866895670637) -->
+    <skip />
+    <!-- no translation found for enable_linux_terminal_summary (5893216510985145320) -->
+    <skip />
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP පරික්ෂාව"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP පරික්ෂා හැසිරීම සකසන්න"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"නිදොස්කරණය"</string>
@@ -686,11 +690,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"සබලයි"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"මෙම වෙනස යෙදීමට ඔබේ උපාංගය නැවත පණ ගැන්විය යුතුය. දැන් නැවත පණ ගන්වන්න හෝ අවලංගු කරන්න."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"රැහැන්ගත හෙඩ්ෆෝන්"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"රැහැන්ගත ශ්‍රව්‍ය"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB ශ්‍රව්‍ය"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"රැහැන්ගත මයික්‍රෆෝනය"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB මයික්‍රෆෝනය"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT මයික්‍රෆෝනය"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ක්‍රියාත්මකයි"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index b807482..74c294b 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Povoľuje funkciu Zlepšené možnosti pripojenia."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Miestny terminál"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Povoliť terminálovú apl. na miestny prístup k prostrediu shell"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Vývojové prostredie Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Spúšťanie terminálu systému Linux v Androide"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Kontrola HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Nastaviť spôsob kontroly HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Ladenie"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Zapnuté"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Zmena sa prejaví až po reštarte zariadenia. Môžete ho teraz reštartovať alebo akciu zrušiť."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Slúchadlá s káblom"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Zvuk cez kábel"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Zvuk cez USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Káblový mikrofón"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Mikrofón s rozhraním USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Mikrofón Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Zapnúť"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index a4c0622..0945cc0 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Omogoči funkcijo Izboljšana povezljivost."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Omogočanje terminalske aplikacije za dostop do lokalne lupine"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Razvojno okolje Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Zagon terminala Linux v Androidu"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Preverjanje HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Nastavi preverjanje HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Odpravljanje napak"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogočeno"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Napravo je treba znova zagnati, da bo ta sprememba uveljavljena. Znova zaženite zdaj ali prekličite."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Žične slušalke"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Žične slušalke"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Zvok USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Žični mikrofon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Mikrofon USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Mikrofon Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Vklop"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 19c4211..e26d428 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -357,6 +357,10 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Aktivizon veçorinë e \"Lidhshmërisë së përmirësuar\"."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminali lokal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivizo aplikacionin terminal që ofron qasje në guaskën lokale"</string>
+    <!-- no translation found for enable_linux_terminal_title (5076044866895670637) -->
+    <skip />
+    <!-- no translation found for enable_linux_terminal_summary (5893216510985145320) -->
+    <skip />
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Kontrolli HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Cakto kontrollin e HDCP-së"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Korrigjimi i gabimeve"</string>
@@ -686,11 +690,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiv"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Pajisja jote duhet të riniset që ky ndryshim të zbatohet. Rinise tani ose anuloje."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Kufje me tela"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Audio me tel"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Pajisja audio me USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Mikrofon me tel"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Mikrofoni me USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Mikrofoni me Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Aktive"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 1862910..d351a12 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Омогућава функцију Побољшано повезивање."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Локални терминал"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Омогући апл. терминала за приступ локалном командном окружењу"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux окружење за програмирање"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Покрените Linux терминал на Android-у"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP провера"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Подешавање понашања HDCP провере"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Отклањање грешака"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Омогућено"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Морате да рестартујете уређај да би се ова промена применила. Рестартујте га одмах или откажите."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Жичане слушалице"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Жичане слушалице"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB аудио"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Жичани микрофон"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB микрофон"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth микрофон"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Укључено"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 1ee80c5..1c1117d 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Aktiverar funktionen Förbättrad anslutning."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Lokal terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivera en terminalapp som ger åtkomst till hyllor lokalt"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-utvecklingsmiljö"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Kör Linux-terminalen på Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontroll"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Konfigurera HDCP-kontroll"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Felsökning"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiverat"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Enheten måste startas om för att ändringen ska börja gälla. Starta om nu eller avbryt."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Hörlur med kabel"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Ljud med kabel"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-ljud"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Mikrofon med kabel"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT-mikrofon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"På"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index d33eafe..820fcc8 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Huwasha kipengele cha Muunganisho Ulioboreshwa."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Kituo cha karibu"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Washa programu ya mwisho inayotoa ufikiaji mkuu wa karibu"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Mazingira ya usanidi wa Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Tumia temino ya Linux kwenye Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Inakagua HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Weka HDCP ya kukagua tabia"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Utatuzi"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Imewashwa"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Ni lazima uwashe tena kifaa chako ili mabadiliko haya yatekelezwe. Washa tena sasa au ughairi."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Kipokea sauti cha kichwani chenye waya"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Kipokea sauti cha kichwani kinachotumia waya"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Sauti ya USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Maikrofoni inayotumia waya"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Maikrofoni ya USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Maikrofoni ya Bluetooth"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Umewashwa"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 2c0781d..98412c1 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"மேம்படுத்தப்பட்ட இணைப்புநிலை அம்சத்தை இயக்கும்."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"அக முனையம்"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"அக ஷெல் அணுகலை வழங்கும் இறுதிப் ஆப்ஸை இயக்கு"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux டெவெலப்மெண்ட் சூழல்"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Androidல் Linux டெர்மினலை இயக்கும்"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP சரிபார்ப்பு"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP சரிபார்க்கும் செயல்பாடுகளை அமை"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"பிழைதிருத்தம்"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"இயக்கப்பட்டது"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"இந்த மாற்றங்கள் செயல்படுத்தப்பட உங்கள் சாதனத்தை மறுபடி தொடங்க வேண்டும். இப்போதே மறுபடி தொடங்கவும் அல்லது ரத்துசெய்யவும்."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"வயர்டு ஹெட்ஃபோன்"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"வயருள்ள ஹெட்ஃபோன்"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB ஆடியோ"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"வயருள்ள மைக்ரோஃபோன்"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB மைக்ரோஃபோன்"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT மைக்ரோஃபோன்"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ஆன்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 145af84..3770bb7 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"మెరుగైన కనెక్టివిటీ ఫీచర్‌ను ఎనేబుల్ చేస్తుంది."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"స్థానిక టెర్మినల్"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"స్థానిక షెల్ యాక్సెస్‌ను అందించే టెర్మినల్ యాప్‌ను ప్రారంభించండి"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux డెవలప్మెంట్ ఎన్విరాన్మెంట్"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Androidలో Linux టెర్మినల్‌ను రన్ చేయండి"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP చెకింగ్‌"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP తనిఖీ ప్రవర్తనను సెట్ చేయండి"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"డీబగ్గింగ్"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ఎనేబుల్ చేయబడింది"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ఈ మార్పును వర్తింపజేయాలంటే మీరు మీ పరికరాన్ని తప్పనిసరిగా రీబూట్ చేయాలి. ఇప్పుడే రీబూట్ చేయండి లేదా రద్దు చేయండి."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"వైర్ ఉన్న హెడ్‌ఫోన్"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"వైర్ ఉన్న ఆడియో"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB ఆడియో"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"వైర్ ఉన్న మైక్రోఫోన్"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB మైక్రోఫోన్"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT మైక్రోఫోన్"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ఆన్‌లో ఉంది"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index ae6585c..57b8f59 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"เปิดใช้ฟีเจอร์การเชื่อมต่อที่ปรับปรุงแล้ว"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"เทอร์มินัลในตัวเครื่อง"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"เปิดใช้งานแอปเทอร์มินัลที่ให้การเข้าถึงเชลล์ในตัวเครื่อง"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"สภาพแวดล้อมในการพัฒนาซอฟต์แวร์ Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"เรียกใช้เทอร์มินัล Linux บน Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"การตรวจสอบ HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"ตั้งค่าการตรวจสอบ HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"การแก้ไขข้อบกพร่อง"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"เปิดใช้"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"คุณต้องรีบูตอุปกรณ์เพื่อให้การเปลี่ยนแปลงนี้มีผล รีบูตเลยหรือยกเลิก"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"หูฟังแบบใช้สาย"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"หูฟังแบบใช้สาย"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"เสียง USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"ไมโครโฟนแบบใช้สาย"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"ไมโครโฟน USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"ไมโครโฟน BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"เปิด"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 6e60e2b..e869e7f 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Ine-enable ang feature na Pinagandang Pagkakonekta."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Lokal na terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Paganahin ang terminal app na nag-aalok ng lokal na shell access"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Development environment ng Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Paganahin ang Linux terminal sa Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Pagsusuring HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP checking behavior"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Pagde-debug"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Na-enable"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Dapat i-reboot ang iyong device para mailapat ang pagbabagong ito. Mag-reboot ngayon o kanselahin."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Wired na headphone"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Wired na audio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Wired na mikropono"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB na mikropono"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT na mikropono"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Naka-on"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 8d709b9..188f5aa 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Gelişmiş Bağlantı özelliğini etkinleştirir."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Yerel terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Yerel kabuk erişimi sunan terminal uygulamasını etkinleştir"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux geliştirme ortamı"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android\'de Linux terminali çalıştırın"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP denetimi"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP denetimini ayarla"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Hata ayıklama"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Etkin"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bu değişikliğin geçerli olması için cihazınızın yeniden başlatılması gerekir. Şimdi yeniden başlatın veya iptal edin."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Kablolu kulaklık"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Kablolu ses"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB ses cihazı"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Kablolu mikrofon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"BT mikrofonu"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Açık"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 7b1086c..b82db3a 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Вмикає функцію покращеного з\'єднання."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Локальний термінал"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Увімк. програму-термінал, що надає локальний доступ до оболонки"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Середовище Linux для розробки"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Запуск термінала Linux на Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Перевірка HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Порядок перевірки HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Налагодження"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Увімкнено"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Щоб застосувати ці зміни, потрібний перезапуск. Перезапустіть пристрій або скасуйте зміни."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Дротові навушники"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Дротовий аудіопристрій"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB-аудіо"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Дротовий мікрофон"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB-мікрофон"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth-мікрофон"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Увімкнено"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index db00474..43f03a2 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"بہتر کردہ کنیکٹوٹی کی خصوصیات کو فعال کرتا ہے۔"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"مقامی ٹرمینل"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"مقامی شیل رسائی پیش کرنے والی ٹرمینل ایپ فعال کریں"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"‏‫Linux ڈیولپمنٹ ماحول"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"‏‫Android پر Linux ٹرمینل چلائیں"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"‏HDCP چیکنگ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏HDCP چیکنگ برتاؤ سیٹ کریں"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ڈیبگ کرنا"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"فعال"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"اس تبدیلی کو لاگو کرنے کے ليے آپ کے آلہ کو ریبوٹ کرنا ضروری ہے۔ ابھی ریبوٹ کریں یا منسوخ کریں۔"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"تار والا ہیڈ فون"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"تار والا ہیڈ فون"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"‏‫USB آڈیو"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"تار والا مائیکروفون"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"‏‫USB مائیکروفون"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"‏‫BT مائیکروفون"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"آن"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 833863e..685d6e6 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Kuchaytirilgan aloqa funksiyasini ishga tushiradi."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Mahalliy terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Mahalliy terminalga kirishga ruxsat beruvchi terminal ilovani faollashtirish"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux dasturlash muhiti"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android orqali Linux terminalini ishga tushirish"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP tekshiruvi"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCPni tekshirish tartibi"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Nosozliklarni tuzatish"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Yoniq"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Oʻzgarishlar kuchga kirishi uchun qurilmani oʻchirib yoqing. Buni hozir yoki keyinroq bajarishingiz mumkin."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Simli quloqlik"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Simli audio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB audio"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Simli mikrofon"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB mikrofon"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Bluetooth mikrofon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Yoniq"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index fba3a13..7e98afd 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Bật tính năng Kết nối nâng cao."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Dòng lệnh cục bộ"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Bật ứng dụng dòng lệnh cung cấp quyền truy cập vỏ cục bộ"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Môi trường phát triển Linux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Chạy thiết bị đầu cuối Linux trên Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Kiểm tra HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Đặt hành vi kiểm tra HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Gỡ lỗi"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Đã bật"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bạn phải khởi động lại thiết bị để áp dụng sự thay đổi này. Hãy khởi động lại ngay hoặc hủy."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Tai nghe có dây"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Thiết bị âm thanh có dây"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Âm thanh qua cổng USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Micrô có dây"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Micrô USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Micrô BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Đang bật"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 29a4590..0f3373e 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"启用增强连接性功能。"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"本地终端"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"启用终端应用,以便在本地访问 Shell"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux 开发环境"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"在 Android 上运行 Linux 终端"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 检查"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"设置 HDCP 检查行为"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"调试"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已启用"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"设备必须重新启动才能应用此更改。您可以立即重新启动或取消。"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"有线耳机"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"有线音频"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB 音频"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"有线麦克风"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB 麦克风"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"蓝牙麦克风"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"开启"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 71fd6ee..d6ec1ca 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"啟用強化連線功能。"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"本機終端機"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"啟用可提供本機命令介面存取權的終端機應用程式"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux 開發環境"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"在 Android 上執行 Linux 終端機"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 檢查"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"設定 HDCP 檢查行為"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"除錯"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已啟用"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"你的裝置必須重新開機,才能套用此變更。請立即重新開機或取消。"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"有線耳機"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"有線音響"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB 音訊"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"有線麥克風"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB 麥克風"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"藍牙麥克風"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"開啟"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index b5700bc..08bf732 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"啟用「加強型連線」功能。"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"本機終端機"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"啟用可提供本機命令介面存取權的終端機應用程式"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux 開發環境"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"在 Android 上執行 Linux 終端機"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 檢查"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"設定 HDCP 檢查行為"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"偵錯"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已啟用"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"裝置必須重新啟動才能套用這項變更。請立即重新啟動或取消變更。"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"有線耳機"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"有線音訊"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB 音訊"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"有線麥克風"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"USB 麥克風"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"藍牙麥克風"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"開啟"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 2f822b3..ad4f045 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -357,6 +357,8 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Inika amandla isici Sokuxhumeka Okuthuthukisiwe."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Itheminali yasendaweni"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Nika amandla uhlelo lokusebenza letheminali olunikeza ukufinyelela kwasendaweni kwe-shell"</string>
+    <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Indawo yokuthuthukiswa yeLinux"</string>
+    <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Sebenzisa itheminali yeLinux ku-Android"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Ihlola i-HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Hlela ukuhlola ukuziphatha kwe-HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Ilungisa inkinga"</string>
@@ -686,11 +688,9 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Inikwe amandla"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Kufanele idivayisi yakho iqaliswe ukuze lolu shintsho lusebenze. Qalisa manje noma khansela."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Amahedifoni anentambo"</string>
-    <!-- no translation found for media_transfer_headphone_name (1157798825650178478) -->
-    <skip />
+    <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Umsindo onentambo"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Umsindo we-USB"</string>
-    <!-- no translation found for media_transfer_wired_device_mic_name (7115192790725088698) -->
-    <skip />
+    <string name="media_transfer_wired_device_mic_name" msgid="7115192790725088698">"Imakrofoni enentambo"</string>
     <string name="media_transfer_usb_device_mic_name" msgid="7171789543226269822">"Imakrofoni ye-USB"</string>
     <string name="media_transfer_bt_device_mic_name" msgid="1870669402238687618">"Imakrofoni ye-BT"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Vuliwe"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/data/repository/DeviceSettingServiceConnection.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/data/repository/DeviceSettingServiceConnection.kt
index a33fcc6..c16366e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/data/repository/DeviceSettingServiceConnection.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/data/repository/DeviceSettingServiceConnection.kt
@@ -279,7 +279,7 @@
                             getService(intent, IDeviceSettingsProviderService.Stub::asInterface)
                                 .stateIn(
                                     coroutineScope.plus(backgroundCoroutineContext),
-                                    SharingStarted.WhileSubscribed(),
+                                    SharingStarted.WhileSubscribed(stopTimeoutMillis = SERVICE_CONNECTION_STOP_MILLIS),
                                     ServiceConnectionStatus.Connecting,
                                 )
                         },
@@ -370,5 +370,6 @@
         const val CONFIG_SERVICE_PACKAGE_NAME = "DEVICE_SETTINGS_CONFIG_PACKAGE_NAME"
         const val CONFIG_SERVICE_CLASS_NAME = "DEVICE_SETTINGS_CONFIG_CLASS"
         const val CONFIG_SERVICE_INTENT_ACTION = "DEVICE_SETTINGS_CONFIG_ACTION"
+        const val SERVICE_CONNECTION_STOP_MILLIS = 1000L
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
index 63661f6..4f315a2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
@@ -74,23 +74,7 @@
             new AudioDeviceCallback() {
                 @Override
                 public void onAudioDevicesAdded(@NonNull AudioDeviceInfo[] addedDevices) {
-                    // Activate the last hot plugged valid input device, to match the output device
-                    // behavior.
-                    @AudioDeviceType int deviceTypeToActivate = mSelectedInputDeviceType;
-                    for (AudioDeviceInfo info : addedDevices) {
-                        if (InputMediaDevice.isSupportedInputDevice(info.getType())) {
-                            deviceTypeToActivate = info.getType();
-                        }
-                    }
-
-                    // Only activate if we find a different valid input device. e.g. if none of the
-                    // addedDevices is supported input device, we don't need to activate anything.
-                    if (mSelectedInputDeviceType != deviceTypeToActivate) {
-                        mSelectedInputDeviceType = deviceTypeToActivate;
-                        AudioDeviceAttributes deviceAttributes =
-                                createInputDeviceAttributes(mSelectedInputDeviceType);
-                        setPreferredDeviceForAllPresets(deviceAttributes);
-                    }
+                    applyDefaultSelectedTypeToAllPresets();
                 }
 
                 @Override
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
index d808a25..782cee2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
@@ -24,7 +24,6 @@
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -139,18 +138,6 @@
                 /* address= */ "");
     }
 
-    private AudioDeviceAttributes getUsbHeadsetDeviceAttributes() {
-        return new AudioDeviceAttributes(
-                AudioDeviceAttributes.ROLE_INPUT,
-                AudioDeviceInfo.TYPE_USB_HEADSET,
-                /* address= */ "");
-    }
-
-    private AudioDeviceAttributes getHdmiDeviceAttributes() {
-        return new AudioDeviceAttributes(
-                AudioDeviceAttributes.ROLE_INPUT, AudioDeviceInfo.TYPE_HDMI, /* address= */ "");
-    }
-
     private void onPreferredDevicesForCapturePresetChanged(InputRouteManager inputRouteManager) {
         final List<AudioDeviceAttributes> audioDeviceAttributesList =
                 new ArrayList<AudioDeviceAttributes>();
@@ -316,47 +303,21 @@
     }
 
     @Test
-    public void onAudioDevicesAdded_shouldActivateAddedDevice() {
+    public void onAudioDevicesAdded_shouldApplyDefaultSelectedDeviceToAllPresets() {
         final AudioManager audioManager = mock(AudioManager.class);
+        AudioDeviceAttributes wiredHeadsetDeviceAttributes = getWiredHeadsetDeviceAttributes();
+        when(audioManager.getDevicesForAttributes(INPUT_ATTRIBUTES))
+                .thenReturn(Collections.singletonList(wiredHeadsetDeviceAttributes));
+
         InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager);
         AudioDeviceInfo[] devices = {mockWiredHeadsetInfo()};
         inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices);
 
-        // The only added wired headset will be activated.
+        // Called twice, one after initiation, the other after onAudioDevicesAdded call.
+        verify(audioManager, atLeast(2)).getDevicesForAttributes(INPUT_ATTRIBUTES);
         for (@MediaRecorder.Source int preset : PRESETS) {
-            verify(audioManager, atLeast(1))
-                    .setPreferredDeviceForCapturePreset(preset, getWiredHeadsetDeviceAttributes());
-        }
-    }
-
-    @Test
-    public void onAudioDevicesAdded_shouldActivateLastAddedDevice() {
-        final AudioManager audioManager = mock(AudioManager.class);
-        InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager);
-        AudioDeviceInfo[] devices = {mockWiredHeadsetInfo(), mockUsbHeadsetInfo()};
-        inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices);
-
-        // When adding multiple valid input devices, the last added device (usb headset in this
-        // case) will be activated.
-        for (@MediaRecorder.Source int preset : PRESETS) {
-            verify(audioManager, never())
-                    .setPreferredDeviceForCapturePreset(preset, getWiredHeadsetDeviceAttributes());
-            verify(audioManager, atLeast(1))
-                    .setPreferredDeviceForCapturePreset(preset, getUsbHeadsetDeviceAttributes());
-        }
-    }
-
-    @Test
-    public void onAudioDevicesAdded_doNotActivateInvalidAddedDevice() {
-        final AudioManager audioManager = mock(AudioManager.class);
-        InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager);
-        AudioDeviceInfo[] devices = {mockHdmiInfo()};
-        inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices);
-
-        // Do not activate since HDMI is not a valid input device.
-        for (@MediaRecorder.Source int preset : PRESETS) {
-            verify(audioManager, never())
-                    .setPreferredDeviceForCapturePreset(preset, getHdmiDeviceAttributes());
+            verify(audioManager, atLeast(2))
+                    .setPreferredDeviceForCapturePreset(preset, wiredHeadsetDeviceAttributes);
         }
     }
 
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index d39b564..1659c9e 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -903,8 +903,8 @@
                         Settings.System.EGG_MODE, // I am the lolrus
                         Settings.System.END_BUTTON_BEHAVIOR, // bug?
                         Settings.System.DEFAULT_DEVICE_FONT_SCALE, // Non configurable
-                        Settings.System
-                                .HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY,
+                        Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY,
+                        Settings.System.INPUT_GAIN_INDEX_SETTINGS,
                         // candidate for backup?
                         Settings.System.LOCKSCREEN_DISABLED, // ?
                         Settings.System.MEDIA_BUTTON_RECEIVER, // candidate for backup?
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index bcfd8f6..0a68e67 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -90,10 +90,10 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
-import libcore.io.Streams;
-
 import com.google.android.collect.Lists;
 
+import libcore.io.Streams;
+
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -171,8 +171,8 @@
     static final String EXTRA_DESCRIPTION = "android.intent.extra.DESCRIPTION";
     static final String EXTRA_ORIGINAL_INTENT = "android.intent.extra.ORIGINAL_INTENT";
     static final String EXTRA_INFO = "android.intent.extra.INFO";
-    static final String EXTRA_EXTRA_ATTACHMENT_URI =
-            "android.intent.extra.EXTRA_ATTACHMENT_URI";
+    static final String EXTRA_EXTRA_ATTACHMENT_URIS =
+            "android.intent.extra.EXTRA_ATTACHMENT_URIS";
 
     private static final int MSG_SERVICE_COMMAND = 1;
     private static final int MSG_DELAYED_SCREENSHOT = 2;
@@ -682,10 +682,11 @@
         long nonce = intent.getLongExtra(EXTRA_BUGREPORT_NONCE, 0);
         String baseName = getBugreportBaseName(bugreportType);
         String name = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
-        Uri extraAttachment = intent.getParcelableExtra(EXTRA_EXTRA_ATTACHMENT_URI, Uri.class);
+        List<Uri> extraAttachments =
+                intent.getParcelableArrayListExtra(EXTRA_EXTRA_ATTACHMENT_URIS, Uri.class);
 
         BugreportInfo info = new BugreportInfo(mContext, baseName, name, shareTitle,
-                shareDescription, bugreportType, mBugreportsDir, nonce, extraAttachment);
+                shareDescription, bugreportType, mBugreportsDir, nonce, extraAttachments);
         synchronized (mLock) {
             if (info.bugreportFile.exists()) {
                 Log.e(TAG, "Failed to start bugreport generation, the requested bugreport file "
@@ -1233,9 +1234,13 @@
             clipData.addItem(new ClipData.Item(null, null, null, screenshotUri));
             attachments.add(screenshotUri);
         }
-        if (info.extraAttachment != null) {
-            clipData.addItem(new ClipData.Item(null, null, null, info.extraAttachment));
-            attachments.add(info.extraAttachment);
+        if (info.extraAttachments != null) {
+            info.extraAttachments.forEach(it -> {
+                if (it != null) {
+                    clipData.addItem(new ClipData.Item(null, null, null, it));
+                    attachments.add(it);
+                }
+            });
         }
         intent.setClipData(clipData);
         intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachments);
@@ -2096,7 +2101,7 @@
         final long nonce;
 
         @Nullable
-        public Uri extraAttachment = null;
+        public List<Uri> extraAttachments = null;
 
         private final Object mLock = new Object();
 
@@ -2106,7 +2111,7 @@
         BugreportInfo(Context context, String baseName, String name,
                 @Nullable String shareTitle, @Nullable String shareDescription,
                 @BugreportParams.BugreportMode int type, File bugreportsDir, long nonce,
-                @Nullable Uri extraAttachment) {
+                @Nullable List<Uri> extraAttachments) {
             this.context = context;
             this.name = this.initialName = name;
             this.shareTitle = shareTitle == null ? "" : shareTitle;
@@ -2115,7 +2120,7 @@
             this.nonce = nonce;
             this.baseName = baseName;
             this.bugreportFile = new File(bugreportsDir, getFileName(this, ".zip"));
-            this.extraAttachment = extraAttachment;
+            this.extraAttachments = extraAttachments;
         }
 
         void createBugreportFile() {
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-de/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-de/strings.xml
index 9d9b05a..f9e548b 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-de/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-de/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menü für Bedienungshilfen"</string>
-    <string name="accessibility_menu_intro" msgid="3164193281544042394">"Über das Menü für Bedienungshilfen lässt sich ein großes Menü zur Bedienung deines Geräts auf dem Bildschirm öffnen. Du kannst beispielsweise das Gerät sperren, die Lautstärke und Helligkeit anpassen und Screenshots machen."</string>
+    <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menü „Bedienungshilfen“"</string>
+    <string name="accessibility_menu_intro" msgid="3164193281544042394">"Über das Menü „Bedienungshilfen“ lässt sich ein großes Menü zur Bedienung deines Geräts auf dem Bildschirm öffnen. Du kannst beispielsweise das Gerät sperren, die Lautstärke und Helligkeit anpassen und Screenshots machen."</string>
     <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
     <string name="a11y_settings_label" msgid="3977714687248445050">"Einstellungen für Bedienungshilfen"</string>
@@ -20,7 +20,7 @@
     <string name="brightness_down_label" msgid="7115662941913272072">"Helligkeit verringern"</string>
     <string name="previous_button_content_description" msgid="840869171117765966">"Zum vorherigen Bildschirm"</string>
     <string name="next_button_content_description" msgid="6810058269847364406">"Zum nächsten Bildschirm"</string>
-    <string name="accessibility_menu_description" msgid="4458354794093858297">"Über das Menü für Bedienungshilfen lässt sich ein großes Menü zur Bedienung deines Geräts auf dem Bildschirm öffnen. Du kannst beispielsweise das Gerät sperren, die Lautstärke und Helligkeit anpassen und Screenshots machen."</string>
+    <string name="accessibility_menu_description" msgid="4458354794093858297">"Über das Menü „Bedienungshilfen“ lässt sich ein großes Menü zur Bedienung deines Geräts auf dem Bildschirm öffnen. Du kannst beispielsweise das Gerät sperren, die Lautstärke und Helligkeit anpassen und Screenshots machen."</string>
     <string name="accessibility_menu_summary" msgid="340071398148208130">"Gerät mit großem Menü steuern"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Einstellungen für das Menü „Bedienungshilfen“"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Große Schaltflächen"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-km/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-km/strings.xml
index e091dd9..02c091e 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-km/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-km/strings.xml
@@ -3,7 +3,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="accessibility_menu_service_name" msgid="730136711554740131">"ម៉ឺនុយ​ភាពងាយស្រួល"</string>
     <string name="accessibility_menu_intro" msgid="3164193281544042394">"ម៉ឺនុយភាពងាយស្រួលផ្ដល់ម៉ឺនុយធំនៅលើអេក្រង់ ដើម្បីគ្រប់គ្រងឧបករណ៍របស់អ្នក។ អ្នកអាច​ចាក់សោឧបករណ៍​របស់អ្នក គ្រប់គ្រងកម្រិតសំឡេងនិងពន្លឺ ថតរូបអេក្រង់ និង​អ្វីៗច្រើនទៀត។"</string>
-    <string name="assistant_label" msgid="6796392082252272356">"ជំនួយការ"</string>
+    <string name="assistant_label" msgid="6796392082252272356">"Google Assistant"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"Google Assistant"</string>
     <string name="a11y_settings_label" msgid="3977714687248445050">"ការកំណត់​ភាព​ងាយស្រួល"</string>
     <string name="power_label" msgid="7699720321491287839">"ថាមពល"</string>
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index a984b7d..7b8dddb 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1529,6 +1529,13 @@
 }
 
 flag {
+  name: "shade_window_goes_around"
+  namespace: "systemui"
+  description: "Enables the shade window to move between displays"
+  bug: "362719719"
+}
+
+flag {
    name: "media_projection_request_attribution_fix"
    namespace: "systemui"
    description: "Ensure MediaProjection consent requests are properly attributed"
@@ -1559,6 +1566,16 @@
 }
 
 flag {
+   name: "hide_ringer_button_in_single_volume_mode"
+   namespace: "systemui"
+   description: "When the device is in single volume mode, hide the ringer button because it doesn't work"
+   bug: "374870615"
+   metadata {
+       purpose: PURPOSE_BUGFIX
+   }
+}
+
+flag {
     name: "qs_tile_detailed_view"
     namespace: "systemui"
     description: "Enables the tile detailed view UI."
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/back/FlingOnBackAnimationCallback.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/back/FlingOnBackAnimationCallback.kt
new file mode 100644
index 0000000..cd2dd04
--- /dev/null
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/back/FlingOnBackAnimationCallback.kt
@@ -0,0 +1,166 @@
+/*
+ * 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.animation.back
+
+import android.util.TimeUtils
+import android.view.Choreographer
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.VelocityTracker
+import android.view.animation.Interpolator
+import android.window.BackEvent
+import android.window.OnBackAnimationCallback
+import com.android.app.animation.Interpolators
+import com.android.internal.dynamicanimation.animation.DynamicAnimation
+import com.android.internal.dynamicanimation.animation.FlingAnimation
+import com.android.internal.dynamicanimation.animation.FloatValueHolder
+import com.android.window.flags.Flags.predictiveBackTimestampApi
+
+private const val FLING_FRICTION = 6f
+private const val SCALE_FACTOR = 100f
+
+/**
+ * Enhanced [OnBackAnimationCallback] with automatic fling animation and interpolated progress.
+ *
+ * Simplifies back gesture handling by animating flings and emitting processed events through
+ * `compat` functions. Customize progress interpolation with an optional [Interpolator].
+ *
+ * @param progressInterpolator [Interpolator] for progress, defaults to
+ *   [Interpolators.BACK_GESTURE].
+ */
+abstract class FlingOnBackAnimationCallback(
+    val progressInterpolator: Interpolator = Interpolators.BACK_GESTURE
+) : OnBackAnimationCallback {
+
+    private val velocityTracker = VelocityTracker.obtain()
+    private var lastBackEvent: BackEvent? = null
+    private var downTime: Long? = null
+
+    private var backInvokedFlingAnim: FlingAnimation? = null
+    private val backInvokedFlingUpdateListener =
+        DynamicAnimation.OnAnimationUpdateListener { _, progress: Float, _ ->
+            lastBackEvent?.let {
+                val backEvent =
+                    BackEvent(
+                        it.touchX,
+                        it.touchY,
+                        progress / SCALE_FACTOR,
+                        it.swipeEdge,
+                        it.frameTimeMillis,
+                    )
+                onBackProgressedCompat(backEvent)
+            }
+        }
+    private val backInvokedFlingEndListener =
+        DynamicAnimation.OnAnimationEndListener { _, _, _, _ ->
+            onBackInvokedCompat()
+            reset()
+        }
+
+    abstract fun onBackStartedCompat(backEvent: BackEvent)
+
+    abstract fun onBackProgressedCompat(backEvent: BackEvent)
+
+    abstract fun onBackInvokedCompat()
+
+    abstract fun onBackCancelledCompat()
+
+    final override fun onBackStarted(backEvent: BackEvent) {
+        if (backInvokedFlingAnim != null) {
+            // This should never happen but let's call onBackInvokedCompat() just in case there is
+            // still a fling animation in progress
+            onBackInvokedCompat()
+        }
+        reset()
+        if (predictiveBackTimestampApi()) {
+            downTime = backEvent.frameTimeMillis
+        }
+        onBackStartedCompat(backEvent)
+    }
+
+    final override fun onBackProgressed(backEvent: BackEvent) {
+        val interpolatedProgress = progressInterpolator.getInterpolation(backEvent.progress)
+        if (predictiveBackTimestampApi()) {
+            velocityTracker.addMovement(
+                MotionEvent.obtain(
+                    /* downTime */ downTime!!,
+                    /* eventTime */ backEvent.frameTimeMillis,
+                    /* action */ ACTION_MOVE,
+                    /* x */ interpolatedProgress * SCALE_FACTOR,
+                    /* y */ 0f,
+                    /* metaState */ 0,
+                )
+            )
+            lastBackEvent =
+                BackEvent(
+                    backEvent.touchX,
+                    backEvent.touchY,
+                    interpolatedProgress,
+                    backEvent.swipeEdge,
+                    backEvent.frameTimeMillis,
+                )
+        } else {
+            lastBackEvent =
+                BackEvent(
+                    backEvent.touchX,
+                    backEvent.touchY,
+                    interpolatedProgress,
+                    backEvent.swipeEdge,
+                )
+        }
+        lastBackEvent?.let { onBackProgressedCompat(it) }
+    }
+
+    final override fun onBackInvoked() {
+        if (predictiveBackTimestampApi() && lastBackEvent != null) {
+            velocityTracker.computeCurrentVelocity(1000)
+            backInvokedFlingAnim =
+                FlingAnimation(FloatValueHolder())
+                    .setStartValue((lastBackEvent?.progress ?: 0f) * SCALE_FACTOR)
+                    .setFriction(FLING_FRICTION)
+                    .setStartVelocity(velocityTracker.xVelocity)
+                    .setMinValue(0f)
+                    .setMaxValue(SCALE_FACTOR)
+                    .also {
+                        it.addUpdateListener(backInvokedFlingUpdateListener)
+                        it.addEndListener(backInvokedFlingEndListener)
+                        it.start()
+                        // do an animation-frame immediately to prevent idle frame
+                        it.doAnimationFrame(
+                            Choreographer.getInstance().lastFrameTimeNanos / TimeUtils.NANOS_PER_MS
+                        )
+                    }
+        } else {
+            onBackInvokedCompat()
+            reset()
+        }
+    }
+
+    final override fun onBackCancelled() {
+        onBackCancelledCompat()
+        reset()
+    }
+
+    private fun reset() {
+        velocityTracker.clear()
+        backInvokedFlingAnim?.removeEndListener(backInvokedFlingEndListener)
+        backInvokedFlingAnim?.removeUpdateListener(backInvokedFlingUpdateListener)
+        lastBackEvent = null
+        backInvokedFlingAnim = null
+        downTime = null
+    }
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt
index 8740d14..f708de3 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt
@@ -23,6 +23,7 @@
 import android.window.OnBackAnimationCallback
 import android.window.OnBackInvokedDispatcher
 import android.window.OnBackInvokedDispatcher.Priority
+import com.android.app.animation.Interpolators
 
 /**
  * Generates an [OnBackAnimationCallback] given a [backAnimationSpec]. [onBackProgressed] will be
@@ -40,16 +41,16 @@
     onBackInvoked: () -> Unit = {},
     onBackCancelled: () -> Unit = {},
 ): OnBackAnimationCallback {
-    return object : OnBackAnimationCallback {
+    return object : FlingOnBackAnimationCallback(progressInterpolator = Interpolators.LINEAR) {
         private var initialY = 0f
         private val lastTransformation = BackTransformation()
 
-        override fun onBackStarted(backEvent: BackEvent) {
+        override fun onBackStartedCompat(backEvent: BackEvent) {
             initialY = backEvent.touchY
             onBackStarted(backEvent)
         }
 
-        override fun onBackProgressed(backEvent: BackEvent) {
+        override fun onBackProgressedCompat(backEvent: BackEvent) {
             val progressY = (backEvent.touchY - initialY) / displayMetrics.heightPixels
 
             backAnimationSpec.getBackTransformation(
@@ -61,11 +62,11 @@
             onBackProgressed(lastTransformation)
         }
 
-        override fun onBackInvoked() {
+        override fun onBackInvokedCompat() {
             onBackInvoked()
         }
 
-        override fun onBackCancelled() {
+        override fun onBackCancelledCompat() {
             onBackCancelled()
         }
     }
@@ -86,7 +87,7 @@
             override fun onViewAttachedToWindow(v: View) {
                 onBackInvokedDispatcher.registerOnBackInvokedCallback(
                     priority,
-                    onBackAnimationCallback
+                    onBackAnimationCallback,
                 )
             }
 
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
index c95d120..ae75e6c 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
@@ -74,6 +74,8 @@
 import androidx.lifecycle.findViewTreeViewModelStoreOwner
 import androidx.lifecycle.setViewTreeLifecycleOwner
 import androidx.lifecycle.setViewTreeViewModelStoreOwner
+import androidx.savedstate.findViewTreeSavedStateRegistryOwner
+import androidx.savedstate.setViewTreeSavedStateRegistryOwner
 import com.android.systemui.animation.Expandable
 import com.android.systemui.animation.TransitionAnimator
 import kotlin.math.max
@@ -173,9 +175,7 @@
     val wrappedContent =
         remember(content) {
             movableContentOf { expandable: Expandable ->
-                CompositionLocalProvider(
-                    LocalContentColor provides contentColor,
-                ) {
+                CompositionLocalProvider(LocalContentColor provides contentColor) {
                     // We make sure that the content itself (wrapped by the background) is at least
                     // 40.dp, which is the same as the M3 buttons. This applies even if onClick is
                     // null, to make it easier to write expandables that are sometimes clickable and
@@ -253,7 +253,7 @@
                 modifier
                     .updateExpandableSize()
                     .then(minInteractiveSizeModifier)
-                    .drawWithContent { /* Don't draw anything when the dialog is shown. */}
+                    .drawWithContent { /* Don't draw anything when the dialog is shown. */ }
                     .onGloballyPositioned {
                         controller.boundsInComposeViewRoot.value = it.boundsInRoot()
                     }
@@ -288,7 +288,7 @@
                     .border(controller)
                     .onGloballyPositioned {
                         controller.boundsInComposeViewRoot.value = it.boundsInRoot()
-                    },
+                    }
             ) {
                 wrappedContent(controller.expandable)
             }
@@ -365,19 +365,14 @@
                 }
 
             // Set the owners.
-            val overlayViewGroup =
-                getOverlayViewGroup(
-                    context,
-                    overlay,
-                )
+            val overlayViewGroup = getOverlayViewGroup(context, overlay)
 
             overlayViewGroup.setViewTreeLifecycleOwner(composeViewRoot.findViewTreeLifecycleOwner())
             overlayViewGroup.setViewTreeViewModelStoreOwner(
                 composeViewRoot.findViewTreeViewModelStoreOwner()
             )
-            ViewTreeSavedStateRegistryOwner.set(
-                overlayViewGroup,
-                ViewTreeSavedStateRegistryOwner.get(composeViewRoot),
+            overlayViewGroup.setViewTreeSavedStateRegistryOwner(
+                composeViewRoot.findViewTreeSavedStateRegistryOwner()
             )
 
             composeView.setParentCompositionContext(compositionContext)
@@ -405,10 +400,7 @@
     }
 }
 
-internal fun measureAndLayoutComposeViewInOverlay(
-    view: View,
-    state: TransitionAnimator.State,
-) {
+internal fun measureAndLayoutComposeViewInOverlay(view: View, state: TransitionAnimator.State) {
     val exactWidth = state.width
     val exactHeight = state.height
     view.measure(
@@ -474,7 +466,7 @@
                 topLeft = Offset(halfStroke, halfStroke),
                 size = Size(size.width - strokeWidth, size.height - strokeWidth),
                 cornerRadius = cornerRadius.shrink(halfStroke),
-                style = borderStroke
+                style = borderStroke,
             )
         }
     } else {
@@ -494,11 +486,7 @@
         if (border != null) {
             // Copied from androidx.compose.foundation.Border.kt.
             val strokeWidth = border.width.toPx()
-            val path =
-                createRoundRectPath(
-                    (outline as Outline.Rounded).roundRect,
-                    strokeWidth,
-                )
+            val path = createRoundRectPath((outline as Outline.Rounded).roundRect, strokeWidth)
 
             drawPath(path, border.brush)
         }
@@ -510,10 +498,7 @@
  *
  * Copied from androidx.compose.foundation.Border.kt.
  */
-private fun createRoundRectPath(
-    roundedRect: RoundRect,
-    strokeWidth: Float,
-): Path {
+private fun createRoundRectPath(roundedRect: RoundRect, strokeWidth: Float): Path {
     return Path().apply {
         addRoundRect(roundedRect)
         val insetPath =
@@ -532,7 +517,7 @@
         topLeftCornerRadius = roundedRect.topLeftCornerRadius.shrink(widthPx),
         topRightCornerRadius = roundedRect.topRightCornerRadius.shrink(widthPx),
         bottomLeftCornerRadius = roundedRect.bottomLeftCornerRadius.shrink(widthPx),
-        bottomRightCornerRadius = roundedRect.bottomRightCornerRadius.shrink(widthPx)
+        bottomRightCornerRadius = roundedRect.bottomRightCornerRadius.shrink(widthPx),
     )
 
 /**
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/ViewTreeSavedStateRegistryOwner.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/ViewTreeSavedStateRegistryOwner.kt
deleted file mode 100644
index cdc9a52..0000000
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/ViewTreeSavedStateRegistryOwner.kt
+++ /dev/null
@@ -1,34 +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.compose.animation
-
-import android.view.View
-import androidx.savedstate.SavedStateRegistryOwner
-import androidx.savedstate.findViewTreeSavedStateRegistryOwner
-import androidx.savedstate.setViewTreeSavedStateRegistryOwner
-
-// TODO(b/262222023): Remove this workaround and import the new savedstate libraries in tm-qpr-dev
-// instead.
-object ViewTreeSavedStateRegistryOwner {
-    fun set(view: View, owner: SavedStateRegistryOwner?) {
-        view.setViewTreeSavedStateRegistryOwner(owner)
-    }
-
-    fun get(view: View): SavedStateRegistryOwner? {
-        return view.findViewTreeSavedStateRegistryOwner()
-    }
-}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/grid/Grids.kt b/packages/SystemUI/compose/core/src/com/android/compose/grid/Grids.kt
similarity index 100%
rename from packages/SystemUI/compose/scene/src/com/android/compose/grid/Grids.kt
rename to packages/SystemUI/compose/core/src/com/android/compose/grid/Grids.kt
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/ui/graphics/DrawInContainer.kt b/packages/SystemUI/compose/core/src/com/android/compose/ui/graphics/DrawInContainer.kt
new file mode 100644
index 0000000..3115191
--- /dev/null
+++ b/packages/SystemUI/compose/core/src/com/android/compose/ui/graphics/DrawInContainer.kt
@@ -0,0 +1,199 @@
+/*
+ * 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.compose.ui.graphics
+
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawWithContent
+import androidx.compose.ui.graphics.Path
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.ui.graphics.drawscope.DrawScope
+import androidx.compose.ui.graphics.drawscope.clipPath
+import androidx.compose.ui.graphics.drawscope.translate
+import androidx.compose.ui.graphics.layer.GraphicsLayer
+import androidx.compose.ui.graphics.layer.drawLayer
+import androidx.compose.ui.layout.LayoutCoordinates
+import androidx.compose.ui.layout.layout
+import androidx.compose.ui.layout.positionInWindow
+import androidx.compose.ui.modifier.ModifierLocalModifierNode
+import androidx.compose.ui.node.DrawModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.node.requireDensity
+import androidx.compose.ui.node.requireGraphicsContext
+import androidx.compose.ui.node.requireLayoutCoordinates
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.util.fastForEach
+
+/**
+ * Define this as a container into which other composables can be drawn using [drawInContainer].
+ *
+ * The elements redirected to this container will be drawn above the content of this composable.
+ */
+fun Modifier.container(state: ContainerState): Modifier {
+    return layout { measurable, constraints ->
+            val p = measurable.measure(constraints)
+            layout(p.width, p.height) {
+                val coords = coordinates
+                if (coords != null && !isLookingAhead) {
+                    state.lastCoords = coords
+                }
+
+                p.place(0, 0)
+            }
+        }
+        .drawWithContent {
+            drawContent()
+            state.drawInOverlay(this)
+        }
+}
+
+/**
+ * Draw this composable into the container associated to [state].
+ *
+ * @param state the state of the container into which we should draw this composable.
+ * @param enabled whether the redirection of the drawing to the container is enabled.
+ * @param zIndex the z-index of the composable in the container.
+ * @param clipPath the clip path applied when drawing this composable into the container.
+ */
+fun Modifier.drawInContainer(
+    state: ContainerState,
+    enabled: () -> Boolean = { true },
+    zIndex: Float = 0f,
+    clipPath: (LayoutDirection, Density) -> Path? = { _, _ -> null },
+): Modifier {
+    return this.then(
+        DrawInContainerElement(
+            state = state,
+            enabled = enabled,
+            zIndex = zIndex,
+            clipPath = clipPath,
+        )
+    )
+}
+
+class ContainerState {
+    private var renderers = mutableStateListOf<LayerRenderer>()
+    internal var lastCoords: LayoutCoordinates? = null
+
+    internal fun onLayerRendererAttached(renderer: LayerRenderer) {
+        renderers.add(renderer)
+        renderers.sortBy { it.zIndex }
+    }
+
+    internal fun onLayerRendererDetached(renderer: LayerRenderer) {
+        renderers.remove(renderer)
+    }
+
+    internal fun drawInOverlay(drawScope: DrawScope) {
+        renderers.fastForEach { it.drawInOverlay(drawScope) }
+    }
+}
+
+internal interface LayerRenderer {
+    val zIndex: Float
+
+    fun drawInOverlay(drawScope: DrawScope)
+}
+
+private data class DrawInContainerElement(
+    var state: ContainerState,
+    var enabled: () -> Boolean,
+    val zIndex: Float,
+    val clipPath: (LayoutDirection, Density) -> Path?,
+) : ModifierNodeElement<DrawInContainerNode>() {
+    override fun create(): DrawInContainerNode {
+        return DrawInContainerNode(state, enabled, zIndex, clipPath)
+    }
+
+    override fun update(node: DrawInContainerNode) {
+        node.state = state
+        node.enabled = enabled
+        node.zIndex = zIndex
+        node.clipPath = clipPath
+    }
+}
+
+/**
+ * The implementation of [drawInContainer].
+ *
+ * Note: this was forked from AndroidX RenderInTransitionOverlayNodeElement.kt
+ * (http://shortn/_3dfSFPbm8f).
+ */
+internal class DrawInContainerNode(
+    var state: ContainerState,
+    var enabled: () -> Boolean = { true },
+    zIndex: Float = 0f,
+    var clipPath: (LayoutDirection, Density) -> Path? = { _, _ -> null },
+) : Modifier.Node(), DrawModifierNode, ModifierLocalModifierNode {
+    var zIndex by mutableFloatStateOf(zIndex)
+
+    private inner class LayerWithRenderer(val layer: GraphicsLayer) : LayerRenderer {
+        override val zIndex: Float
+            get() = this@DrawInContainerNode.zIndex
+
+        override fun drawInOverlay(drawScope: DrawScope) {
+            if (enabled()) {
+                with(drawScope) {
+                    val containerCoords =
+                        checkNotNull(state.lastCoords) { "container is not placed" }
+                    val (x, y) =
+                        requireLayoutCoordinates().positionInWindow() -
+                            containerCoords.positionInWindow()
+                    val clipPath = clipPath(layoutDirection, requireDensity())
+                    if (clipPath != null) {
+                        clipPath(clipPath) { translate(x, y) { drawLayer(layer) } }
+                    } else {
+                        translate(x, y) { drawLayer(layer) }
+                    }
+                }
+            }
+        }
+    }
+
+    // Render in-place logic. Depending on the result of `renderInOverlay()`, the content will
+    // either render in-place or in the overlay, but never in both places.
+    override fun ContentDrawScope.draw() {
+        val layer = requireNotNull(layer) { "Error: layer never initialized" }
+        layer.record { this@draw.drawContent() }
+        if (!enabled()) {
+            drawLayer(layer)
+        }
+    }
+
+    val layer: GraphicsLayer?
+        get() = layerWithRenderer?.layer
+
+    private var layerWithRenderer: LayerWithRenderer? = null
+
+    override fun onAttach() {
+        LayerWithRenderer(requireGraphicsContext().createGraphicsLayer()).let {
+            state.onLayerRendererAttached(it)
+            layerWithRenderer = it
+        }
+    }
+
+    override fun onDetach() {
+        layerWithRenderer?.let {
+            state.onLayerRendererDetached(it)
+            requireGraphicsContext().releaseGraphicsLayer(it.layer)
+        }
+    }
+}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/ui/graphics/DrawInOverlay.kt b/packages/SystemUI/compose/core/src/com/android/compose/ui/graphics/DrawInOverlay.kt
new file mode 100644
index 0000000..f5c3a83
--- /dev/null
+++ b/packages/SystemUI/compose/core/src/com/android/compose/ui/graphics/DrawInOverlay.kt
@@ -0,0 +1,79 @@
+/*
+ * 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.compose.ui.graphics
+
+import android.view.View
+import android.view.ViewGroupOverlay
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCompositionContext
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.unit.IntSize
+import androidx.lifecycle.findViewTreeLifecycleOwner
+import androidx.lifecycle.findViewTreeViewModelStoreOwner
+import androidx.lifecycle.setViewTreeLifecycleOwner
+import androidx.lifecycle.setViewTreeViewModelStoreOwner
+import androidx.savedstate.findViewTreeSavedStateRegistryOwner
+import androidx.savedstate.setViewTreeSavedStateRegistryOwner
+
+/**
+ * Draw this composable in the [overlay][ViewGroupOverlay] of the [current ComposeView][LocalView].
+ */
+@Composable
+fun Modifier.drawInOverlay(): Modifier {
+    val containerState = remember { ContainerState() }
+    val context = LocalContext.current
+    val localView = LocalView.current
+    val compositionContext = rememberCompositionContext()
+    val displayMetrics = context.resources.displayMetrics
+    val displaySize = IntSize(displayMetrics.widthPixels, displayMetrics.heightPixels)
+
+    DisposableEffect(containerState, context, localView, compositionContext, displaySize) {
+        val overlay = localView.rootView.overlay as ViewGroupOverlay
+        val view =
+            ComposeView(context).apply {
+                setParentCompositionContext(compositionContext)
+
+                // Set the owners.
+                setViewTreeLifecycleOwner(localView.findViewTreeLifecycleOwner())
+                setViewTreeViewModelStoreOwner(localView.findViewTreeViewModelStoreOwner())
+                setViewTreeSavedStateRegistryOwner(localView.findViewTreeSavedStateRegistryOwner())
+
+                setContent { Box(Modifier.fillMaxSize().container(containerState)) }
+            }
+
+        overlay.add(view)
+
+        // Make the ComposeView as big as the display. We have to manually measure and layout the
+        // View given that there is no layout pass in Android overlays.
+        view.measure(
+            View.MeasureSpec.makeSafeMeasureSpec(displaySize.width, View.MeasureSpec.EXACTLY),
+            View.MeasureSpec.makeSafeMeasureSpec(displaySize.height, View.MeasureSpec.EXACTLY),
+        )
+        view.layout(0, 0, displaySize.width, displaySize.height)
+
+        onDispose { overlay.remove(view) }
+    }
+
+    return this.drawInContainer(containerState, enabled = { true })
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationScrimNestedScrollConnection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationScrimNestedScrollConnection.kt
index 8b9e927..e4c60e1 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationScrimNestedScrollConnection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationScrimNestedScrollConnection.kt
@@ -18,6 +18,8 @@
 
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
+import androidx.compose.ui.util.fastCoerceAtLeast
+import androidx.compose.ui.util.fastCoerceAtMost
 import com.android.compose.nestedscroll.PriorityNestedScrollConnection
 
 /**
@@ -44,7 +46,7 @@
         orientation = Orientation.Vertical,
         // scrolling up and inner content is taller than the scrim, so scrim needs to
         // expand; content can scroll once scrim is at the minScrimOffset.
-        canStartPreScroll = { offsetAvailable, offsetBeforeStart ->
+        canStartPreScroll = { offsetAvailable, offsetBeforeStart, _ ->
             offsetAvailable < 0 &&
                 offsetBeforeStart == 0f &&
                 contentHeight() > minVisibleScrimHeight() &&
@@ -52,36 +54,38 @@
         },
         // scrolling down and content is done scrolling to top. After that, the scrim
         // needs to collapse; collapse the scrim until it is at the maxScrimOffset.
-        canStartPostScroll = { offsetAvailable, _ ->
+        canStartPostScroll = { offsetAvailable, _, _ ->
             offsetAvailable > 0 && (scrimOffset() < maxScrimOffset || isCurrentGestureOverscroll())
         },
         canStartPostFling = { false },
-        canContinueScroll = {
-            val currentHeight = scrimOffset()
-            minScrimOffset() < currentHeight && currentHeight < maxScrimOffset
-        },
-        canScrollOnFling = true,
+        canStopOnPreFling = { false },
         onStart = { offsetAvailable -> onStart(offsetAvailable) },
-        onScroll = { offsetAvailable ->
+        onScroll = { offsetAvailable, _ ->
             val currentHeight = scrimOffset()
             val amountConsumed =
                 if (offsetAvailable > 0) {
                     val amountLeft = maxScrimOffset - currentHeight
-                    offsetAvailable.coerceAtMost(amountLeft)
+                    offsetAvailable.fastCoerceAtMost(amountLeft)
                 } else {
                     val amountLeft = minScrimOffset() - currentHeight
-                    offsetAvailable.coerceAtLeast(amountLeft)
+                    offsetAvailable.fastCoerceAtLeast(amountLeft)
                 }
             snapScrimOffset(currentHeight + amountConsumed)
             amountConsumed
         },
-        // Don't consume the velocity on pre/post fling
         onStop = { velocityAvailable ->
             onStop(velocityAvailable)
             if (scrimOffset() < minScrimOffset()) {
                 animateScrimOffset(minScrimOffset())
             }
-            { 0f }
+            // Don't consume the velocity on pre/post fling
+            0f
+        },
+        onCancel = {
+            onStop(0f)
+            if (scrimOffset() < minScrimOffset()) {
+                animateScrimOffset(minScrimOffset())
+            }
         },
     )
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackNestedScrollConnection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackNestedScrollConnection.kt
index a706585..edb05eb 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackNestedScrollConnection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackNestedScrollConnection.kt
@@ -28,6 +28,7 @@
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastCoerceAtLeast
 import com.android.compose.nestedscroll.PriorityNestedScrollConnection
 import kotlin.math.max
 import kotlin.math.roundToInt
@@ -86,21 +87,25 @@
 ): PriorityNestedScrollConnection {
     return PriorityNestedScrollConnection(
         orientation = Orientation.Vertical,
-        canStartPreScroll = { _, _ -> false },
-        canStartPostScroll = { offsetAvailable, offsetBeforeStart ->
+        canStartPreScroll = { _, _, _ -> false },
+        canStartPostScroll = { offsetAvailable, offsetBeforeStart, _ ->
             offsetAvailable < 0f && offsetBeforeStart < 0f && !canScrollForward()
         },
         canStartPostFling = { velocityAvailable -> velocityAvailable < 0f && !canScrollForward() },
-        canContinueScroll = { stackOffset() > 0f },
-        canScrollOnFling = true,
+        canStopOnPreFling = { false },
         onStart = { offsetAvailable -> onStart(offsetAvailable) },
-        onScroll = { offsetAvailable ->
-            onScroll(offsetAvailable)
-            offsetAvailable
+        onScroll = { offsetAvailable, _ ->
+            val minOffset = 0f
+            val consumed = offsetAvailable.fastCoerceAtLeast(minOffset - stackOffset())
+            if (consumed != 0f) {
+                onScroll(consumed)
+            }
+            consumed
         },
         onStop = { velocityAvailable ->
             onStop(velocityAvailable)
-            suspend { velocityAvailable }
+            velocityAvailable
         },
+        onCancel = { onStop(0f) },
     )
 }
diff --git a/packages/SystemUI/compose/scene/Android.bp b/packages/SystemUI/compose/scene/Android.bp
index af1172b..682c49cfd 100644
--- a/packages/SystemUI/compose/scene/Android.bp
+++ b/packages/SystemUI/compose/scene/Android.bp
@@ -40,6 +40,8 @@
     static_libs: [
         "androidx.compose.runtime_runtime",
         "androidx.compose.material3_material3",
+
+        "PlatformComposeCore",
     ],
 
     kotlincflags: ["-Xjvm-default=all"],
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index e5ef79b..8469007 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -27,9 +27,10 @@
 import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.compose.animation.scene.content.state.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified
 import com.android.compose.nestedscroll.PriorityNestedScrollConnection
-import com.android.compose.nestedscroll.SuspendedValue
 import kotlin.math.absoluteValue
 
+internal typealias SuspendedValue<T> = suspend () -> T
+
 internal interface DraggableHandler {
     /**
      * Start a drag in the given [startedPosition], with the given [overSlop] and number of
@@ -612,7 +613,7 @@
 
         return PriorityNestedScrollConnection(
             orientation = orientation,
-            canStartPreScroll = { offsetAvailable, offsetBeforeStart ->
+            canStartPreScroll = { offsetAvailable, offsetBeforeStart, _ ->
                 canChangeScene =
                     if (isExternalOverscrollGesture()) false else offsetBeforeStart == 0f
 
@@ -644,7 +645,7 @@
                 isIntercepting = true
                 true
             },
-            canStartPostScroll = { offsetAvailable, offsetBeforeStart ->
+            canStartPostScroll = { offsetAvailable, offsetBeforeStart, _ ->
                 val behavior: NestedScrollBehavior =
                     when {
                         offsetAvailable > 0f -> topOrLeftBehavior
@@ -709,8 +710,10 @@
 
                 canStart
             },
-            canContinueScroll = { true },
-            canScrollOnFling = false,
+            // We need to maintain scroll priority even if the scene transition can no longer
+            // consume the scroll gesture to allow us to return to the previous scene.
+            canStopOnScroll = { _, _ -> false },
+            canStopOnPreFling = { true },
             onStart = { offsetAvailable ->
                 val pointersInfo = pointersInfo()
                 dragController =
@@ -720,7 +723,7 @@
                         overSlop = if (isIntercepting) 0f else offsetAvailable,
                     )
             },
-            onScroll = { offsetAvailable ->
+            onScroll = { offsetAvailable, _ ->
                 val controller = dragController ?: error("Should be called after onStart")
 
                 val pointersInfo = pointersInfoOwner.pointersInfo()
@@ -735,10 +738,23 @@
             },
             onStop = { velocityAvailable ->
                 val controller = dragController ?: error("Should be called after onStart")
-
-                controller
-                    .onStop(velocity = velocityAvailable, canChangeContent = canChangeScene)
-                    .also { dragController = null }
+                try {
+                    controller
+                        .onStop(velocity = velocityAvailable, canChangeContent = canChangeScene)
+                        .invoke()
+                } finally {
+                    // onStop might still be running when a new gesture begins.
+                    // To prevent conflicts, we should only remove the drag controller if it's the
+                    // same one that was active initially.
+                    if (dragController == controller) {
+                        dragController = null
+                    }
+                }
+            },
+            onCancel = {
+                val controller = dragController ?: error("Should be called after onStart")
+                controller.onStop(velocity = 0f, canChangeContent = canChangeScene)
+                dragController = null
             },
         )
     }
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 ebe1df4..f14622f 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
@@ -48,10 +48,13 @@
 import androidx.compose.ui.util.fastCoerceIn
 import androidx.compose.ui.util.fastForEachReversed
 import androidx.compose.ui.util.lerp
+import com.android.compose.animation.scene.Element.State
 import com.android.compose.animation.scene.content.Content
 import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.compose.animation.scene.transformation.PropertyTransformation
 import com.android.compose.animation.scene.transformation.SharedElementTransformation
+import com.android.compose.modifiers.thenIf
+import com.android.compose.ui.graphics.drawInContainer
 import com.android.compose.ui.util.lerp
 import kotlin.math.roundToInt
 import kotlinx.coroutines.launch
@@ -146,10 +149,58 @@
     // 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
-    return then(ElementModifier(layoutImpl, currentTransitionStates, content, key))
+    return thenIf(layoutImpl.state.isElevationPossible(content.key, key)) {
+            Modifier.maybeElevateInContent(layoutImpl, content, key, currentTransitionStates)
+        }
+        .then(ElementModifier(layoutImpl, currentTransitionStates, content, key))
         .testTag(key.testTag)
 }
 
+private fun Modifier.maybeElevateInContent(
+    layoutImpl: SceneTransitionLayoutImpl,
+    content: Content,
+    key: ElementKey,
+    transitionStates: List<TransitionState>,
+): Modifier {
+    fun isSharedElement(
+        stateByContent: Map<ContentKey, State>,
+        transition: TransitionState.Transition,
+    ): Boolean {
+        fun inFromContent() = transition.fromContent in stateByContent
+        fun inToContent() = transition.toContent in stateByContent
+        fun inCurrentScene() = transition.currentScene in stateByContent
+
+        return if (transition is TransitionState.Transition.ReplaceOverlay) {
+            (inFromContent() && (inToContent() || inCurrentScene())) ||
+                (inToContent() && inCurrentScene())
+        } else {
+            inFromContent() && inToContent()
+        }
+    }
+
+    return drawInContainer(
+        content.containerState,
+        enabled = {
+            val stateByContent = layoutImpl.elements.getValue(key).stateByContent
+            val state = elementState(transitionStates, isInContent = { it in stateByContent })
+
+            state is TransitionState.Transition &&
+                state.transformationSpec
+                    .transformations(key, content.key)
+                    .shared
+                    ?.elevateInContent == content.key &&
+                isSharedElement(stateByContent, state) &&
+                isSharedElementEnabled(key, state) &&
+                shouldPlaceElement(
+                    layoutImpl,
+                    content.key,
+                    layoutImpl.elements.getValue(key),
+                    state,
+                )
+        },
+    )
+}
+
 /**
  * An element associated to [ElementNode]. Note that this element does not support updates as its
  * arguments should always be the same.
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
index a9a8668..e1e2411 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
@@ -19,13 +19,16 @@
 import android.util.Log
 import androidx.annotation.VisibleForTesting
 import androidx.compose.runtime.Stable
+import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.util.fastAll
+import androidx.compose.ui.util.fastAny
 import androidx.compose.ui.util.fastFilter
 import androidx.compose.ui.util.fastForEach
 import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.compose.animation.scene.transformation.SharedElementTransformation
 import com.android.compose.animation.scene.transition.link.LinkedTransition
 import com.android.compose.animation.scene.transition.link.StateLink
 import kotlin.math.absoluteValue
@@ -271,6 +274,14 @@
         mutableStateOf(listOf(TransitionState.Idle(initialScene, initialOverlays)))
         private set
 
+    /**
+     * The flattened list of [SharedElementTransformation] within all the transitions in
+     * [transitionStates].
+     */
+    private val transformationsWithElevation: List<SharedElementTransformation> by derivedStateOf {
+        transformationsWithElevation(transitionStates)
+    }
+
     override val currentScene: SceneKey
         get() = transitionState.currentScene
 
@@ -743,6 +754,42 @@
 
         animate()
     }
+
+    private fun transformationsWithElevation(
+        transitionStates: List<TransitionState>
+    ): List<SharedElementTransformation> {
+        return buildList {
+            transitionStates.fastForEach { state ->
+                if (state !is TransitionState.Transition) {
+                    return@fastForEach
+                }
+
+                state.transformationSpec.transformations.fastForEach { transformation ->
+                    if (
+                        transformation is SharedElementTransformation &&
+                            transformation.elevateInContent != null
+                    ) {
+                        add(transformation)
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Return whether we might need to elevate [element] (or any element if [element] is `null`) in
+     * [content].
+     *
+     * This is used to compose `Modifier.container()` and `Modifier.drawInContainer()` only when
+     * necessary, for performance.
+     */
+    internal fun isElevationPossible(content: ContentKey, element: ElementKey?): Boolean {
+        if (transformationsWithElevation.isEmpty()) return false
+        return transformationsWithElevation.fastAny { transformation ->
+            transformation.elevateInContent == content &&
+                (element == null || transformation.matcher.matches(element, content))
+        }
+    }
 }
 
 private const val TAG = "SceneTransitionLayoutState"
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
index 205267d..f0043e1 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
@@ -27,7 +27,6 @@
 import androidx.compose.ui.unit.IntSize
 import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.compose.animation.scene.content.state.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified
-import com.android.compose.nestedscroll.SuspendedValue
 import kotlin.math.absoluteValue
 import kotlinx.coroutines.CompletableDeferred
 
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
index e825c6e..dc26b6b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
@@ -204,8 +204,17 @@
      *
      * @param enabled whether the matched element(s) should actually be shared in this transition.
      *   Defaults to true.
+     * @param elevateInContent the content in which we should elevate the element when it is shared,
+     *   drawing above all other composables of that content. If `null` (the default), we will
+     *   simply draw this element in its original location. If not `null`, it has to be either the
+     *   [fromContent][TransitionState.Transition.fromContent] or
+     *   [toContent][TransitionState.Transition.toContent] of the transition.
      */
-    fun sharedElement(matcher: ElementMatcher, enabled: Boolean = true)
+    fun sharedElement(
+        matcher: ElementMatcher,
+        enabled: Boolean = true,
+        elevateInContent: ContentKey? = null,
+    )
 
     /**
      * Adds the transformations in [builder] but in reversed order. This allows you to partially
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
index a5ad999..269d91b0 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
@@ -249,8 +249,22 @@
         reversed = false
     }
 
-    override fun sharedElement(matcher: ElementMatcher, enabled: Boolean) {
-        transformations.add(SharedElementTransformation(matcher, enabled))
+    override fun sharedElement(
+        matcher: ElementMatcher,
+        enabled: Boolean,
+        elevateInContent: ContentKey?,
+    ) {
+        check(
+            elevateInContent == null ||
+                elevateInContent == transition.fromContent ||
+                elevateInContent == transition.toContent
+        ) {
+            "elevateInContent (${elevateInContent?.debugName}) should be either fromContent " +
+                "(${transition.fromContent.debugName}) or toContent " +
+                "(${transition.toContent.debugName})"
+        }
+
+        transformations.add(SharedElementTransformation(matcher, enabled, elevateInContent))
     }
 
     override fun timestampRange(
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 c8407b1..8187e39 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
@@ -51,6 +51,9 @@
 import com.android.compose.animation.scene.element
 import com.android.compose.animation.scene.modifiers.noResizeDuringTransitions
 import com.android.compose.animation.scene.nestedScrollToScene
+import com.android.compose.modifiers.thenIf
+import com.android.compose.ui.graphics.ContainerState
+import com.android.compose.ui.graphics.container
 
 /** A content defined in a [SceneTransitionLayout], i.e. a scene or an overlay. */
 @Stable
@@ -62,6 +65,7 @@
     zIndex: Float,
 ) {
     internal val scope = ContentScopeImpl(layoutImpl, content = this)
+    val containerState = ContainerState()
 
     var content by mutableStateOf(content)
     var zIndex by mutableFloatStateOf(zIndex)
@@ -82,6 +86,9 @@
                     val placeable = measurable.measure(constraints)
                     layout(placeable.width, placeable.height) { placeable.place(0, 0) }
                 }
+                .thenIf(layoutImpl.state.isElevationPossible(content = key, element = null)) {
+                    Modifier.container(containerState)
+                }
                 .testTag(key.testTag)
         ) {
             scope.content()
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
index 9bb3023..de7f418 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
@@ -52,6 +52,7 @@
 internal class SharedElementTransformation(
     override val matcher: ElementMatcher,
     internal val enabled: Boolean,
+    internal val elevateInContent: ContentKey?,
 ) : Transformation
 
 /** A transformation that changes the value of an element property, like its size or offset. */
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/LargeTopAppBarNestedScrollConnection.kt b/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/LargeTopAppBarNestedScrollConnection.kt
index 4ae3235..ecf64b7 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/LargeTopAppBarNestedScrollConnection.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/LargeTopAppBarNestedScrollConnection.kt
@@ -18,6 +18,8 @@
 
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
+import androidx.compose.ui.util.fastCoerceAtLeast
+import androidx.compose.ui.util.fastCoerceAtMost
 
 /**
  * A [NestedScrollConnection] that listens for all vertical scroll events and responds in the
@@ -43,35 +45,32 @@
         orientation = Orientation.Vertical,
         // When swiping up, the LargeTopAppBar will shrink (to [minHeight]) and the content will
         // expand. Then, you can then scroll down the content.
-        canStartPreScroll = { offsetAvailable, offsetBeforeStart ->
+        canStartPreScroll = { offsetAvailable, offsetBeforeStart, _ ->
             offsetAvailable < 0 && offsetBeforeStart == 0f && height() > minHeight()
         },
         // When swiping down, the content will scroll up until it reaches the top. Then, the
         // LargeTopAppBar will expand until it reaches its [maxHeight].
-        canStartPostScroll = { offsetAvailable, _ ->
+        canStartPostScroll = { offsetAvailable, _, _ ->
             offsetAvailable > 0 && height() < maxHeight()
         },
         canStartPostFling = { false },
-        canContinueScroll = {
-            val currentHeight = height()
-            minHeight() < currentHeight && currentHeight < maxHeight()
-        },
-        canScrollOnFling = true,
+        canStopOnPreFling = { false },
         onStart = { /* do nothing */ },
-        onScroll = { offsetAvailable ->
+        onScroll = { offsetAvailable, _ ->
             val currentHeight = height()
             val amountConsumed =
                 if (offsetAvailable > 0) {
                     val amountLeft = maxHeight() - currentHeight
-                    offsetAvailable.coerceAtMost(amountLeft)
+                    offsetAvailable.fastCoerceAtMost(amountLeft)
                 } else {
                     val amountLeft = minHeight() - currentHeight
-                    offsetAvailable.coerceAtLeast(amountLeft)
+                    offsetAvailable.fastCoerceAtLeast(amountLeft)
                 }
             onHeightChanged(currentHeight + amountConsumed)
             amountConsumed
         },
         // Don't consume the velocity on pre/post fling
-        onStop = { { 0f } },
+        onStop = { 0f },
+        onCancel = { /* do nothing */ },
     )
 }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt b/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt
index a3641e6..57d236b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt
@@ -16,37 +16,64 @@
 
 package com.android.compose.nestedscroll
 
+import androidx.compose.animation.core.AnimationState
+import androidx.compose.animation.core.DecayAnimationSpec
+import androidx.compose.animation.core.animateDecay
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
 import androidx.compose.ui.input.nestedscroll.NestedScrollSource
 import androidx.compose.ui.unit.Velocity
 import com.android.compose.ui.util.SpaceVectorConverter
+import kotlin.math.abs
 import kotlin.math.sign
-
-internal typealias SuspendedValue<T> = suspend () -> T
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.async
+import kotlinx.coroutines.coroutineScope
 
 /**
- * This [NestedScrollConnection] waits for a child to scroll ([onPreScroll] or [onPostScroll]), and
- * then decides (via [canStartPreScroll] or [canStartPostScroll]) if it should take over scrolling.
- * If it does, it will scroll before its children, until [canContinueScroll] allows it.
+ * A [NestedScrollConnection] that intercepts scroll events in priority mode.
  *
- * Note: Call [reset] before destroying this object to make sure you always get a call to [onStop]
- * after [onStart].
+ * Priority mode allows this connection to take control over scroll events within a nested scroll
+ * hierarchy. When in priority mode, this connection consumes scroll events before its children,
+ * enabling custom scrolling behaviors like sticky headers.
  *
+ * @param orientation The orientation of the scroll.
+ * @param canStartPreScroll lambda that returns true if the connection can start consuming scroll
+ *   events in pre-scroll mode.
+ * @param canStartPostScroll lambda that returns true if the connection can start consuming scroll
+ *   events in post-scroll mode.
+ * @param canStartPostFling lambda that returns true if the connection can start consuming scroll
+ *   events in post-fling mode.
+ * @param canStopOnScroll lambda that returns true if the connection can stop consuming scroll
+ *   events in scroll mode.
+ * @param canStopOnPreFling lambda that returns true if the connection can stop consuming scroll
+ *   events in pre-fling (i.e. as soon as the user lifts their fingers).
+ * @param onStart lambda that is called when the connection starts consuming scroll events.
+ * @param onScroll lambda that is called when the connection consumes a scroll event and returns the
+ *   consumed amount.
+ * @param onStop lambda that is called when the connection stops consuming scroll events and returns
+ *   the consumed velocity.
+ * @param onCancel lambda that is called when the connection is cancelled.
  * @sample LargeTopAppBarNestedScrollConnection
  * @sample com.android.compose.animation.scene.NestedScrollHandlerImpl.nestedScrollConnection
  */
 class PriorityNestedScrollConnection(
     orientation: Orientation,
-    private val canStartPreScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean,
-    private val canStartPostScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean,
+    private val canStartPreScroll:
+        (offsetAvailable: Float, offsetBeforeStart: Float, source: NestedScrollSource) -> Boolean,
+    private val canStartPostScroll:
+        (offsetAvailable: Float, offsetBeforeStart: Float, source: NestedScrollSource) -> Boolean,
     private val canStartPostFling: (velocityAvailable: Float) -> Boolean,
-    private val canContinueScroll: (source: NestedScrollSource) -> Boolean,
-    private val canScrollOnFling: Boolean,
+    private val canStopOnScroll: (available: Float, consumed: Float) -> Boolean = { _, consumed ->
+        consumed == 0f
+    },
+    private val canStopOnPreFling: () -> Boolean,
     private val onStart: (offsetAvailable: Float) -> Unit,
-    private val onScroll: (offsetAvailable: Float) -> Float,
-    private val onStop: (velocityAvailable: Float) -> SuspendedValue<Float>,
+    private val onScroll: (offsetAvailable: Float, source: NestedScrollSource) -> Float,
+    private val onStop: suspend (velocityAvailable: Float) -> Float,
+    private val onCancel: () -> Unit,
 ) : NestedScrollConnection, SpaceVectorConverter by SpaceVectorConverter(orientation) {
 
     /** In priority mode [onPreScroll] events are first consumed by the parent, via [onScroll]. */
@@ -54,6 +81,9 @@
 
     private var offsetScrolledBeforePriorityMode = 0f
 
+    /** This job allows us to interrupt the onStop animation */
+    private var onStopJob: Deferred<Float> = CompletableDeferred(0f)
+
     override fun onPostScroll(
         consumed: Offset,
         available: Offset,
@@ -64,62 +94,48 @@
         // the beginning or from the last fling gesture.
         val offsetBeforeStart = offsetScrolledBeforePriorityMode - availableFloat
 
-        if (
-            isPriorityMode ||
-                (source == NestedScrollSource.SideEffect && !canScrollOnFling) ||
-                !canStartPostScroll(availableFloat, offsetBeforeStart)
-        ) {
+        if (isPriorityMode || !canStartPostScroll(availableFloat, offsetBeforeStart, source)) {
             // The priority mode cannot start so we won't consume the available offset.
             return Offset.Zero
         }
 
-        return onPriorityStart(availableFloat).toOffset()
+        return start(availableFloat, source).toOffset()
     }
 
     override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
         if (!isPriorityMode) {
-            if (source == NestedScrollSource.UserInput || canScrollOnFling) {
-                val availableFloat = available.toFloat()
-                if (canStartPreScroll(availableFloat, offsetScrolledBeforePriorityMode)) {
-                    return onPriorityStart(availableFloat).toOffset()
-                }
-                // We want to track the amount of offset consumed before entering priority mode
-                offsetScrolledBeforePriorityMode += availableFloat
+            val availableFloat = available.toFloat()
+            if (canStartPreScroll(availableFloat, offsetScrolledBeforePriorityMode, source)) {
+                return start(availableFloat, source).toOffset()
             }
-
-            return Offset.Zero
-        }
-
-        val availableFloat = available.toFloat()
-        if (!canContinueScroll(source)) {
-            // Step 3a: We have lost priority and we no longer need to intercept scroll events.
-            onPriorityStop(velocity = 0f)
-
-            // We've just reset offsetScrolledBeforePriorityMode to 0f
             // We want to track the amount of offset consumed before entering priority mode
             offsetScrolledBeforePriorityMode += availableFloat
-
             return Offset.Zero
         }
 
-        // Step 2: We have the priority and can consume the scroll events.
-        return onScroll(availableFloat).toOffset()
+        return scroll(available.toFloat(), source).toOffset()
     }
 
     override suspend fun onPreFling(available: Velocity): Velocity {
-        if (isPriorityMode && canScrollOnFling) {
-            // We don't want to consume the velocity, we prefer to continue receiving scroll events.
+        if (!isPriorityMode) {
+            resetOffsetTracker()
             return Velocity.Zero
         }
-        // Step 3b: The finger is lifted, we can stop intercepting scroll events and use the speed
-        // of the fling gesture.
-        return onPriorityStop(velocity = available.toFloat()).invoke().toVelocity()
+
+        if (canStopOnPreFling()) {
+            // Step 3b: The finger is lifted, we can stop intercepting scroll events and use the
+            // velocity of the fling gesture.
+            return stop(velocityAvailable = available.toFloat()).toVelocity()
+        }
+
+        // We don't want to consume the velocity, we prefer to continue receiving scroll events.
+        return Velocity.Zero
     }
 
     override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
         val availableFloat = available.toFloat()
         if (isPriorityMode) {
-            return onPriorityStop(velocity = availableFloat).invoke().toVelocity()
+            return stop(velocityAvailable = availableFloat).toVelocity()
         }
 
         if (!canStartPostFling(availableFloat)) {
@@ -131,10 +147,14 @@
         // TODO(b/291053278): Remove canStartPostFling() and instead make it possible to define the
         // overscroll behavior on the Scene level.
         val smallOffset = availableFloat.sign
-        onPriorityStart(availableOffset = smallOffset)
+        start(
+            availableOffset = smallOffset,
+            source = NestedScrollSource.SideEffect,
+            skipScroll = true,
+        )
 
         // This is the last event of a scroll gesture.
-        return onPriorityStop(availableFloat).invoke().toVelocity()
+        return stop(availableFloat).toVelocity()
     }
 
     /**
@@ -143,36 +163,72 @@
      * TODO(b/303224944) This method should be removed.
      */
     fun reset() {
-        // Step 3c: To ensure that an onStop is always called for every onStart.
-        onPriorityStop(velocity = 0f)
+        if (isPriorityMode) {
+            // Step 3c: To ensure that an onStop (or onCancel) is always called for every onStart.
+            cancel()
+        } else {
+            resetOffsetTracker()
+        }
     }
 
-    private fun onPriorityStart(availableOffset: Float): Float {
-        if (isPriorityMode) {
-            error("This should never happen, onPriorityStart() was called when isPriorityMode")
+    private fun start(
+        availableOffset: Float,
+        source: NestedScrollSource,
+        skipScroll: Boolean = false,
+    ): Float {
+        check(!isPriorityMode) {
+            "This should never happen, start() was called when isPriorityMode"
         }
 
         // Step 1: It's our turn! We start capturing scroll events when one of our children has an
         // available offset following a scroll event.
         isPriorityMode = true
 
+        onStopJob.cancel()
+
         // Note: onStop will be called if we cannot continue to scroll (step 3a), or the finger is
         // lifted (step 3b), or this object has been destroyed (step 3c).
         onStart(availableOffset)
 
-        return onScroll(availableOffset)
+        return if (skipScroll) 0f else scroll(availableOffset, source)
     }
 
-    private fun onPriorityStop(velocity: Float): SuspendedValue<Float> {
-        // We can restart tracking the consumed offsets from scratch.
-        offsetScrolledBeforePriorityMode = 0f
+    private fun scroll(offsetAvailable: Float, source: NestedScrollSource): Float {
+        // Step 2: We have the priority and can consume the scroll events.
+        val consumedByScroll = onScroll(offsetAvailable, source)
 
-        if (!isPriorityMode) {
-            return { 0f }
+        if (canStopOnScroll(offsetAvailable, consumedByScroll)) {
+            // Step 3a: We have lost priority and we no longer need to intercept scroll events.
+            cancel()
+
+            // We've just reset offsetScrolledBeforePriorityMode to 0f
+            // We want to track the amount of offset consumed before entering priority mode
+            offsetScrolledBeforePriorityMode += offsetAvailable - consumedByScroll
         }
 
-        isPriorityMode = false
+        return consumedByScroll
+    }
 
-        return onStop(velocity)
+    /** Reset the tracking of consumed offsets before entering in priority mode. */
+    private fun resetOffsetTracker() {
+        offsetScrolledBeforePriorityMode = 0f
+    }
+
+    private suspend fun stop(velocityAvailable: Float): Float {
+        check(isPriorityMode) { "This should never happen, stop() was called before start()" }
+        isPriorityMode = false
+        resetOffsetTracker()
+
+        return coroutineScope {
+            onStopJob = async { onStop(velocityAvailable) }
+            onStopJob.await()
+        }
+    }
+
+    private fun cancel() {
+        check(isPriorityMode) { "This should never happen, cancel() was called before start()" }
+        isPriorityMode = false
+        resetOffsetTracker()
+        onCancel()
     }
 }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
index fd02148..f24d93f 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
@@ -39,7 +39,6 @@
 import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.compose.animation.scene.content.state.TransitionState.Transition
 import com.android.compose.animation.scene.subjects.assertThat
-import com.android.compose.nestedscroll.SuspendedValue
 import com.android.compose.test.MonotonicClockTestScope
 import com.android.compose.test.runMonotonicClockTest
 import com.android.compose.test.transition
@@ -850,6 +849,34 @@
     }
 
     @Test
+    fun duringATransition_aNewScrollGesture_shouldTakeControl() = runGestureTest {
+        val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
+        // First gesture
+        nestedScroll.scroll(available = downOffset(fractionOfScreen = 0.1f))
+        assertTransition(currentScene = SceneA)
+        nestedScroll.preFling(available = Velocity.Zero)
+        assertTransition(currentScene = SceneA)
+
+        // Second gesture, it starts during onStop() animation
+        nestedScroll.scroll(downOffset(0.1f))
+        assertTransition(currentScene = SceneA)
+
+        // Allows onStop() to complete or cancel
+        advanceUntilIdle()
+
+        // Second gesture continues
+        nestedScroll.scroll(downOffset(0.1f))
+        assertTransition(currentScene = SceneA)
+
+        // Second gesture ends
+        nestedScroll.preFling(available = Velocity.Zero)
+        assertTransition(currentScene = SceneA)
+
+        advanceUntilIdle()
+        assertIdle(currentScene = SceneA)
+    }
+
+    @Test
     fun onPreFling_velocityLowerThanThreshold_remainSameScene() = runGestureTest {
         val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
         nestedScroll.scroll(available = downOffset(fractionOfScreen = 0.1f))
@@ -1296,6 +1323,26 @@
     }
 
     @Test
+    fun scrollKeepPriorityEvenIfWeCanNoLongerScrollOnThatDirection() = runGestureTest {
+        // Overscrolling on scene B does nothing.
+        layoutState.transitions = transitions { overscrollDisabled(SceneB, Orientation.Vertical) }
+        val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeAlways)
+
+        // Overscroll is disabled, it will scroll up to 100%
+        nestedScroll.scroll(available = upOffset(fractionOfScreen = 2f))
+        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 1f)
+
+        // We need to maintain scroll priority even if the scene transition can no longer consume
+        // the scroll gesture.
+        nestedScroll.scroll(available = upOffset(fractionOfScreen = 0.1f))
+        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 1f)
+
+        // A scroll gesture in the opposite direction allows us to return to the previous scene.
+        nestedScroll.scroll(available = downOffset(fractionOfScreen = 0.5f))
+        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.5f)
+    }
+
+    @Test
     fun overscroll_releaseBetween0And100Percent_up() = runGestureTest {
         // Make scene B overscrollable.
         layoutState.transitions = transitions {
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
index c8f6e6d..3df6087 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
@@ -46,7 +46,6 @@
 import androidx.compose.ui.unit.Velocity
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.compose.modifiers.thenIf
-import com.android.compose.nestedscroll.SuspendedValue
 import com.google.common.truth.Truth.assertThat
 import kotlin.properties.Delegates
 import kotlinx.coroutines.coroutineScope
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
index 3001505..2bc9b38 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
@@ -938,6 +938,71 @@
     }
 
     @Test
+    fun scrollKeepPriorityEvenIfWeCanNoLongerScrollOnThatDirection() {
+        val swipeDistance = 100.dp
+        val state =
+            rule.runOnUiThread {
+                MutableSceneTransitionLayoutState(
+                    SceneA,
+                    transitions {
+                        from(SceneA, to = SceneB) { distance = FixedDistance(swipeDistance) }
+                        from(SceneB, to = SceneC) { distance = FixedDistance(swipeDistance) }
+                        overscrollDisabled(SceneB, Orientation.Vertical)
+                    },
+                )
+            }
+        val layoutSize = 200.dp
+        var touchSlop = 0f
+        rule.setContent {
+            touchSlop = LocalViewConfiguration.current.touchSlop
+            SceneTransitionLayout(state, Modifier.size(layoutSize)) {
+                scene(SceneA, userActions = mapOf(Swipe.Down to SceneB, Swipe.Right to SceneC)) {
+                    Box(
+                        Modifier.fillMaxSize()
+                            // A scrollable that does not consume the scroll gesture
+                            .scrollable(rememberScrollableState { 0f }, Orientation.Vertical)
+                    )
+                }
+                scene(SceneB, userActions = mapOf(Swipe.Right to SceneC)) {
+                    Box(Modifier.element(TestElements.Foo).fillMaxSize())
+                }
+                scene(SceneC) { Box(Modifier.fillMaxSize()) }
+            }
+        }
+
+        fun assertTransition(from: SceneKey, to: SceneKey, progress: Float) {
+            val transition = assertThat(state.transitionState).isSceneTransition()
+            assertThat(transition).hasFromScene(from)
+            assertThat(transition).hasToScene(to)
+            assertThat(transition.progress).isEqualTo(progress)
+        }
+
+        // Vertical scroll 100%
+        rule.onRoot().performTouchInput {
+            val middle = (layoutSize / 2).toPx()
+            down(Offset(middle, middle))
+            moveBy(Offset(0f, y = touchSlop + swipeDistance.toPx()), delayMillis = 1_000)
+        }
+        assertTransition(from = SceneA, to = SceneB, progress = 1f)
+
+        // Continue vertical scroll, should be ignored (overscrollDisabled)
+        rule.onRoot().performTouchInput { moveBy(Offset(0f, y = touchSlop), delayMillis = 1_000) }
+        assertTransition(from = SceneA, to = SceneB, progress = 1f)
+
+        // Horizontal scroll, should be ignored
+        rule.onRoot().performTouchInput {
+            moveBy(Offset(x = touchSlop + swipeDistance.toPx(), 0f), delayMillis = 1_000)
+        }
+        assertTransition(from = SceneA, to = SceneB, progress = 1f)
+
+        // Vertical scroll, in the opposite direction
+        rule.onRoot().performTouchInput {
+            moveBy(Offset(0f, -swipeDistance.toPx()), delayMillis = 1_000)
+        }
+        assertTransition(from = SceneA, to = SceneB, progress = 0f)
+    }
+
+    @Test
     fun sceneWithoutSwipesDoesNotConsumeGestures() {
         val buttonTag = "button"
 
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt
index badc43b..1a3b86b 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt
@@ -34,30 +34,31 @@
     private var canStartPreScroll = false
     private var canStartPostScroll = false
     private var canStartPostFling = false
-    private var canContinueScroll = false
+    private var canStopOnPreFling = true
     private var isStarted = false
     private var lastScroll: Float? = null
-    private var returnOnScroll = 0f
+    private var consumeScroll = true
     private var lastStop: Float? = null
-    private var returnOnStop = 0f
+    private var isCancelled: Boolean = false
+    private var consumeStop = true
 
     private val scrollConnection =
         PriorityNestedScrollConnection(
             orientation = Orientation.Vertical,
-            canStartPreScroll = { _, _ -> canStartPreScroll },
-            canStartPostScroll = { _, _ -> canStartPostScroll },
+            canStartPreScroll = { _, _, _ -> canStartPreScroll },
+            canStartPostScroll = { _, _, _ -> canStartPostScroll },
             canStartPostFling = { canStartPostFling },
-            canContinueScroll = { canContinueScroll },
-            canScrollOnFling = false,
+            canStopOnPreFling = { canStopOnPreFling },
             onStart = { isStarted = true },
-            onScroll = {
-                lastScroll = it
-                returnOnScroll
+            onScroll = { offsetAvailable, _ ->
+                lastScroll = offsetAvailable
+                if (consumeScroll) offsetAvailable else 0f
             },
             onStop = {
                 lastStop = it
-                { returnOnStop }
+                if (consumeStop) it else 0f
             },
+            onCancel = { isCancelled = true },
         )
 
     @Test
@@ -85,7 +86,7 @@
         canStartPostScroll = true
         scrollConnection.onPostScroll(
             consumed = Offset.Zero,
-            available = Offset.Zero,
+            available = Offset(1f, 1f),
             source = UserInput,
         )
     }
@@ -136,45 +137,55 @@
     @Test
     fun step2_onPriorityMode_shouldContinueIfAllowed() {
         startPriorityModePostScroll()
-        canContinueScroll = true
 
-        scrollConnection.onPreScroll(available = Offset(1f, 1f), source = UserInput)
+        val scroll1 = scrollConnection.onPreScroll(available = Offset(0f, 1f), source = UserInput)
         assertThat(lastScroll).isEqualTo(1f)
+        assertThat(scroll1.y).isEqualTo(1f)
 
-        canContinueScroll = false
-        scrollConnection.onPreScroll(available = Offset(2f, 2f), source = UserInput)
-        assertThat(lastScroll).isNotEqualTo(2f)
-        assertThat(lastScroll).isEqualTo(1f)
+        consumeScroll = false
+        val scroll2 = scrollConnection.onPreScroll(available = Offset(0f, 2f), source = UserInput)
+        assertThat(lastScroll).isEqualTo(2f)
+        assertThat(scroll2.y).isEqualTo(0f)
     }
 
     @Test
-    fun step3a_onPriorityMode_shouldStopIfCannotContinue() {
+    fun step3a_onPriorityMode_shouldCancelIfCannotContinue() {
         startPriorityModePostScroll()
-        canContinueScroll = false
+        consumeScroll = false
 
-        scrollConnection.onPreScroll(available = Offset.Zero, source = UserInput)
+        scrollConnection.onPreScroll(available = Offset(0f, 1f), source = UserInput)
 
-        assertThat(lastStop).isNotNull()
+        assertThat(isCancelled).isTrue()
     }
 
     @Test
     fun step3b_onPriorityMode_shouldStopOnFling() = runTest {
         startPriorityModePostScroll()
-        canContinueScroll = true
 
         scrollConnection.onPreFling(available = Velocity.Zero)
 
-        assertThat(lastStop).isNotNull()
+        assertThat(lastStop).isEqualTo(0f)
     }
 
     @Test
-    fun step3c_onPriorityMode_shouldStopOnReset() {
+    fun ifCannotStopOnPreFling_shouldStopOnPostFling() = runTest {
         startPriorityModePostScroll()
-        canContinueScroll = true
+        canStopOnPreFling = false
+
+        scrollConnection.onPreFling(available = Velocity.Zero)
+        assertThat(lastStop).isNull()
+
+        scrollConnection.onPostFling(consumed = Velocity.Zero, available = Velocity.Zero)
+        assertThat(lastStop).isEqualTo(0f)
+    }
+
+    @Test
+    fun step3c_onPriorityMode_shouldCancelOnReset() {
+        startPriorityModePostScroll()
 
         scrollConnection.reset()
 
-        assertThat(lastStop).isNotNull()
+        assertThat(isCancelled).isTrue()
     }
 
     @Test
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
index 900971b..2a85823 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
@@ -39,7 +39,7 @@
     val resources: Resources,
     private val hasStepClockAnimation: Boolean = false,
     private val migratedClocks: Boolean = false,
-    private val clockReactiveVariants: Boolean = false,
+    private val isClockReactiveVariantsEnabled: Boolean = false,
 ) : ClockProvider {
     private var messageBuffers: ClockMessageBuffers? = null
 
@@ -54,7 +54,7 @@
             throw IllegalArgumentException("${settings.clockId} is unsupported by $TAG")
         }
 
-        return if (clockReactiveVariants) {
+        return if (isClockReactiveVariantsEnabled) {
             val buffer =
                 messageBuffers?.infraMessageBuffer ?: LogcatOnlyMessageBuffer(LogLevel.INFO)
             val assets = AssetLoader(ctx, ctx, "clocks/", buffer)
@@ -84,7 +84,7 @@
             // TODO(b/352049256): Update placeholder to actual resource
             resources.getDrawable(R.drawable.clock_default_thumbnail, null),
             isReactiveToTone = true,
-            isReactiveToTouch = clockReactiveVariants,
+            isReactiveToTouch = isClockReactiveVariantsEnabled,
             axes = listOf(), // TODO: Ater some picker definition
         )
     }
@@ -103,7 +103,6 @@
                                     timespec = DigitalTimespec.FIRST_DIGIT,
                                     style =
                                         FontTextStyle(
-                                            fontFamily = "google_sans_flex.ttf",
                                             lineHeight = 147.25f,
                                             fontVariation =
                                                 "'wght' 603, 'wdth' 100, 'opsz' 144, 'ROND' 100",
@@ -112,7 +111,6 @@
                                         FontTextStyle(
                                             fontVariation =
                                                 "'wght' 74, 'wdth' 43, 'opsz' 144, 'ROND' 100",
-                                            fontFamily = "google_sans_flex.ttf",
                                             fillColorLight = "#FFFFFFFF",
                                             outlineColor = "#00000000",
                                             renderType = RenderType.CHANGE_WEIGHT,
@@ -131,7 +129,6 @@
                                     timespec = DigitalTimespec.SECOND_DIGIT,
                                     style =
                                         FontTextStyle(
-                                            fontFamily = "google_sans_flex.ttf",
                                             lineHeight = 147.25f,
                                             fontVariation =
                                                 "'wght' 603, 'wdth' 100, 'opsz' 144, 'ROND' 100",
@@ -140,7 +137,6 @@
                                         FontTextStyle(
                                             fontVariation =
                                                 "'wght' 74, 'wdth' 43, 'opsz' 144, 'ROND' 100",
-                                            fontFamily = "google_sans_flex.ttf",
                                             fillColorLight = "#FFFFFFFF",
                                             outlineColor = "#00000000",
                                             renderType = RenderType.CHANGE_WEIGHT,
@@ -159,7 +155,6 @@
                                     timespec = DigitalTimespec.FIRST_DIGIT,
                                     style =
                                         FontTextStyle(
-                                            fontFamily = "google_sans_flex.ttf",
                                             lineHeight = 147.25f,
                                             fontVariation =
                                                 "'wght' 603, 'wdth' 100, 'opsz' 144, 'ROND' 100",
@@ -168,7 +163,6 @@
                                         FontTextStyle(
                                             fontVariation =
                                                 "'wght' 74, 'wdth' 43, 'opsz' 144, 'ROND' 100",
-                                            fontFamily = "google_sans_flex.ttf",
                                             fillColorLight = "#FFFFFFFF",
                                             outlineColor = "#00000000",
                                             renderType = RenderType.CHANGE_WEIGHT,
@@ -187,7 +181,6 @@
                                     timespec = DigitalTimespec.SECOND_DIGIT,
                                     style =
                                         FontTextStyle(
-                                            fontFamily = "google_sans_flex.ttf",
                                             lineHeight = 147.25f,
                                             fontVariation =
                                                 "'wght' 603, 'wdth' 100, 'opsz' 144, 'ROND' 100",
@@ -196,7 +189,6 @@
                                         FontTextStyle(
                                             fontVariation =
                                                 "'wght' 74, 'wdth' 43, 'opsz' 144, 'ROND' 100",
-                                            fontFamily = "google_sans_flex.ttf",
                                             fillColorLight = "#FFFFFFFF",
                                             outlineColor = "#00000000",
                                             renderType = RenderType.CHANGE_WEIGHT,
@@ -221,13 +213,11 @@
                         timespec = DigitalTimespec.TIME_FULL_FORMAT,
                         style =
                             FontTextStyle(
-                                fontFamily = "google_sans_flex.ttf",
                                 fontVariation = "'wght' 600, 'wdth' 100, 'opsz' 144, 'ROND' 100",
                                 fontSizeScale = 0.98f,
                             ),
                         aodStyle =
                             FontTextStyle(
-                                fontFamily = "google_sans_flex.ttf",
                                 fontVariation = "'wght' 133, 'wdth' 43, 'opsz' 144, 'ROND' 100",
                                 fillColorLight = "#FFFFFFFF",
                                 outlineColor = "#00000000",
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerFullscreenSwipeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerFullscreenSwipeTouchHandlerTest.java
index 58c3fec..bd33e52 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerFullscreenSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerFullscreenSwipeTouchHandlerTest.java
@@ -20,7 +20,9 @@
 
 import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -29,11 +31,12 @@
 import android.graphics.Rect;
 import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.FlagsParameterization;
+import android.view.GestureDetector;
 import android.view.GestureDetector.OnGestureListener;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 
-import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.UiEventLogger;
@@ -42,9 +45,12 @@
 import com.android.systemui.ambient.touch.scrim.ScrimController;
 import com.android.systemui.ambient.touch.scrim.ScrimManager;
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel;
+import com.android.systemui.flags.SceneContainerFlagParameterizationKt;
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
 import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.scene.domain.interactor.SceneInteractor;
+import com.android.systemui.scene.ui.view.WindowRootView;
 import com.android.systemui.shared.system.InputChannelCompat;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
@@ -58,10 +64,14 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+import java.util.List;
 import java.util.Optional;
 
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(ParameterizedAndroidJunit4.class)
 @EnableFlags(Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
 @DisableFlags(Flags.FLAG_COMMUNAL_BOUNCER_DO_NOT_MODIFY_PLUGIN_OPEN)
 public class BouncerFullscreenSwipeTouchHandlerTest extends SysuiTestCase {
@@ -114,6 +124,11 @@
     @Mock
     KeyguardInteractor mKeyguardInteractor;
 
+    @Mock
+    WindowRootView mWindowRootView;
+
+    private SceneInteractor mSceneInteractor;
+
     private static final float TOUCH_REGION = .3f;
     private static final float MIN_BOUNCER_HEIGHT = .05f;
 
@@ -124,9 +139,21 @@
             /* flags= */ 0
     );
 
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return SceneContainerFlagParameterizationKt.parameterizeSceneContainerFlag();
+    }
+
+    public BouncerFullscreenSwipeTouchHandlerTest(FlagsParameterization flags) {
+        super();
+        mSetFlagsRule.setFlagsParameterization(flags);
+    }
+
     @Before
     public void setup() {
         mKosmos = new KosmosJavaAdapter(this);
+        mSceneInteractor = spy(mKosmos.getSceneInteractor());
+
         MockitoAnnotations.initMocks(this);
         mTouchHandler = new BouncerSwipeTouchHandler(
                 mKosmos.getTestScope(),
@@ -142,7 +169,9 @@
                 MIN_BOUNCER_HEIGHT,
                 mUiEventLogger,
                 mActivityStarter,
-                mKeyguardInteractor);
+                mKeyguardInteractor,
+                mSceneInteractor,
+                Optional.of(() -> mWindowRootView));
 
         when(mScrimManager.getCurrentController()).thenReturn(mScrimController);
         when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator);
@@ -153,6 +182,38 @@
     }
 
     /**
+     * Makes sure that touches go to the scene container when the flag is on.
+     */
+    @Test
+    @EnableFlags(Flags.FLAG_SCENE_CONTAINER)
+    public void testSwipeUp_sendsTouchesToWindowRootView() {
+        mTouchHandler.onGlanceableTouchAvailable(true);
+        mTouchHandler.onSessionStart(mTouchSession);
+        ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
+                ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
+        verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());
+
+        final OnGestureListener gestureListener = gestureListenerCaptor.getValue();
+
+        final int screenHeight = 100;
+        final float distanceY = screenHeight * 0.42f;
+
+        final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
+                0, screenHeight, 0);
+        final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
+                0, screenHeight - distanceY, 0);
+
+        assertThat(gestureListener.onScroll(event1, event2, 0,
+                distanceY))
+                .isTrue();
+
+        // Ensure only called once
+        verify(mSceneInteractor).onRemoteUserInputStarted(any());
+        verify(mWindowRootView).dispatchTouchEvent(event1);
+        verify(mWindowRootView).dispatchTouchEvent(event2);
+    }
+
+    /**
      * Ensures expansion does not happen for full vertical swipes when touch is not available.
      */
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java
index 9568167..494e0b4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
@@ -37,12 +38,12 @@
 import android.graphics.Region;
 import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.FlagsParameterization;
 import android.view.GestureDetector;
 import android.view.GestureDetector.OnGestureListener;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 
-import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.UiEventLogger;
@@ -52,9 +53,12 @@
 import com.android.systemui.ambient.touch.scrim.ScrimManager;
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel;
+import com.android.systemui.flags.SceneContainerFlagParameterizationKt;
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
 import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.scene.domain.interactor.SceneInteractor;
+import com.android.systemui.scene.ui.view.WindowRootView;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
 import com.android.systemui.shared.system.InputChannelCompat;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -70,10 +74,14 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+import java.util.List;
 import java.util.Optional;
 
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(ParameterizedAndroidJunit4.class)
 @DisableFlags(Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
 public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
     private KosmosJavaAdapter mKosmos;
@@ -122,6 +130,9 @@
     Region mRegion;
 
     @Mock
+    WindowRootView mWindowRootView;
+
+    @Mock
     CommunalViewModel mCommunalViewModel;
 
     @Mock
@@ -130,6 +141,8 @@
     @Captor
     ArgumentCaptor<Rect> mRectCaptor;
 
+    private SceneInteractor mSceneInteractor;
+
     private static final float TOUCH_REGION = .3f;
     private static final int SCREEN_WIDTH_PX = 1024;
     private static final int SCREEN_HEIGHT_PX = 100;
@@ -142,9 +155,21 @@
             /* flags= */ 0
     );
 
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return SceneContainerFlagParameterizationKt.parameterizeSceneContainerFlag();
+    }
+
+    public BouncerSwipeTouchHandlerTest(FlagsParameterization flags) {
+        super();
+        mSetFlagsRule.setFlagsParameterization(flags);
+    }
+
     @Before
     public void setup() {
         mKosmos = new KosmosJavaAdapter(this);
+        mSceneInteractor = spy(mKosmos.getSceneInteractor());
+
         MockitoAnnotations.initMocks(this);
         mTouchHandler = new BouncerSwipeTouchHandler(
                 mKosmos.getTestScope(),
@@ -160,7 +185,10 @@
                 MIN_BOUNCER_HEIGHT,
                 mUiEventLogger,
                 mActivityStarter,
-                mKeyguardInteractor);
+                mKeyguardInteractor,
+                mSceneInteractor,
+                Optional.of(() -> mWindowRootView)
+        );
 
         when(mScrimManager.getCurrentController()).thenReturn(mScrimController);
         when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator);
@@ -367,6 +395,7 @@
      * Makes sure the expansion amount is proportional to (1 - scroll).
      */
     @Test
+    @DisableFlags(Flags.FLAG_SCENE_CONTAINER)
     public void testSwipeUp_setsCorrectExpansionAmount() {
         mTouchHandler.onSessionStart(mTouchSession);
         ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
@@ -380,6 +409,36 @@
     }
 
     /**
+     * Makes sure that touches go to the scene container when the flag is on.
+     */
+    @Test
+    @EnableFlags(Flags.FLAG_SCENE_CONTAINER)
+    public void testSwipeUp_sendsTouchesToWindowRootView() {
+        mTouchHandler.onSessionStart(mTouchSession);
+        ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
+                ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
+        verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());
+
+        final OnGestureListener gestureListener = gestureListenerCaptor.getValue();
+
+        final float distanceY = SCREEN_HEIGHT_PX * 0.42f;
+
+        final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
+                0, SCREEN_HEIGHT_PX, 0);
+        final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
+                0, SCREEN_HEIGHT_PX - distanceY, 0);
+
+        assertThat(gestureListener.onScroll(event1, event2, 0,
+                distanceY))
+                .isTrue();
+
+        // Ensure only called once
+        verify(mSceneInteractor).onRemoteUserInputStarted(any());
+        verify(mWindowRootView).dispatchTouchEvent(event1);
+        verify(mWindowRootView).dispatchTouchEvent(event2);
+    }
+
+    /**
      * Verifies that swiping up when the lock pattern is not secure dismissed dream and consumes
      * the gesture.
      */
@@ -476,6 +535,7 @@
      * Tests that ending an upward swipe before the set threshold leads to bouncer collapsing down.
      */
     @Test
+    @DisableFlags(Flags.FLAG_SCENE_CONTAINER)
     public void testSwipeUpPositionBelowThreshold_collapsesBouncer() {
         final float swipeUpPercentage = .3f;
         final float expansion = 1 - swipeUpPercentage;
@@ -499,6 +559,7 @@
      * Tests that ending an upward swipe above the set threshold will continue the expansion.
      */
     @Test
+    @DisableFlags(Flags.FLAG_SCENE_CONTAINER)
     public void testSwipeUpPositionAboveThreshold_expandsBouncer() {
         final float swipeUpPercentage = .7f;
         final float expansion = 1 - swipeUpPercentage;
@@ -528,6 +589,7 @@
      * Tests that swiping up with a speed above the set threshold will continue the expansion.
      */
     @Test
+    @DisableFlags(Flags.FLAG_SCENE_CONTAINER)
     public void testSwipeUpVelocityAboveMin_expandsBouncer() {
         when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn((float) 0);
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.kt
index 38ea4497..ad636cf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.kt
@@ -18,9 +18,9 @@
 import android.app.DreamManager
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.FlagsParameterization
 import android.view.GestureDetector
 import android.view.MotionEvent
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
@@ -28,14 +28,20 @@
 import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
 import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
+import com.android.systemui.flags.andSceneContainer
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.ui.view.WindowRootView
 import com.android.systemui.shade.ShadeViewController
 import com.android.systemui.shared.system.InputChannelCompat
 import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
 import java.util.Optional
+import javax.inject.Provider
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -47,22 +53,29 @@
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @SmallTest
-@RunWith(AndroidJUnit4::class)
-class ShadeTouchHandlerTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class ShadeTouchHandlerTest(flags: FlagsParameterization) : SysuiTestCase() {
     private var kosmos = testKosmos()
     private var mCentralSurfaces = mock<CentralSurfaces>()
     private var mShadeViewController = mock<ShadeViewController>()
     private var mDreamManager = mock<DreamManager>()
     private var mTouchSession = mock<TouchSession>()
     private var communalViewModel = mock<CommunalViewModel>()
+    private var windowRootView = mock<WindowRootView>()
 
     private lateinit var mTouchHandler: ShadeTouchHandler
 
     private var mGestureListenerCaptor = argumentCaptor<GestureDetector.OnGestureListener>()
     private var mInputListenerCaptor = argumentCaptor<InputChannelCompat.InputEventListener>()
 
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
+
     @Before
     fun setup() {
         mTouchHandler =
@@ -73,7 +86,9 @@
                 mDreamManager,
                 communalViewModel,
                 kosmos.communalSettingsInteractor,
-                TOUCH_HEIGHT
+                kosmos.sceneInteractor,
+                Optional.of(Provider<WindowRootView> { windowRootView }),
+                TOUCH_HEIGHT,
             )
     }
 
@@ -97,7 +112,7 @@
 
     // Verifies that a swipe down forwards captured touches to central surfaces for handling.
     @Test
-    @DisableFlags(Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
+    @DisableFlags(Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX, Flags.FLAG_SCENE_CONTAINER)
     @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
     fun testSwipeDown_communalEnabled_sentToCentralSurfaces() {
         kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
@@ -110,7 +125,11 @@
 
     // Verifies that a swipe down forwards captured touches to the shade view for handling.
     @Test
-    @DisableFlags(Flags.FLAG_COMMUNAL_HUB, Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
+    @DisableFlags(
+        Flags.FLAG_COMMUNAL_HUB,
+        Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX,
+        Flags.FLAG_SCENE_CONTAINER,
+    )
     fun testSwipeDown_communalDisabled_sentToShadeView() {
         swipe(Direction.DOWN)
 
@@ -121,7 +140,7 @@
     // Verifies that a swipe down while dreaming forwards captured touches to the shade view for
     // handling.
     @Test
-    @DisableFlags(Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
+    @DisableFlags(Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX, Flags.FLAG_SCENE_CONTAINER)
     fun testSwipeDown_dreaming_sentToShadeView() {
         whenever(mDreamManager.isDreaming).thenReturn(true)
         swipe(Direction.DOWN)
@@ -130,9 +149,34 @@
         verify(mShadeViewController, times(2)).handleExternalTouch(any())
     }
 
+    // Verifies that a swipe down forwards captured touches to the window root view for handling.
+    @Test
+    @EnableFlags(Flags.FLAG_COMMUNAL_HUB, Flags.FLAG_SCENE_CONTAINER)
+    fun testSwipeDown_sceneContainerEnabled_sentToWindowRootView() {
+        swipe(Direction.DOWN)
+
+        // Both motion events are sent for central surfaces to process.
+        assertThat(kosmos.sceneContainerRepository.isRemoteUserInputOngoing.value).isTrue()
+        verify(windowRootView, times(2)).dispatchTouchEvent(any())
+    }
+
+    // Verifies that a swipe down while dreaming forwards captured touches to the window root view
+    // for handling.
+    @Test
+    @EnableFlags(Flags.FLAG_SCENE_CONTAINER)
+    @DisableFlags(Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
+    fun testSwipeDown_dreaming_sentToWindowRootView() {
+        whenever(mDreamManager.isDreaming).thenReturn(true)
+        swipe(Direction.DOWN)
+
+        // Both motion events are sent for the shade view to process.
+        assertThat(kosmos.sceneContainerRepository.isRemoteUserInputOngoing.value).isTrue()
+        verify(windowRootView, times(2)).dispatchTouchEvent(any())
+    }
+
     // Verifies that a swipe up is not forwarded to central surfaces.
     @Test
-    @DisableFlags(Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
+    @DisableFlags(Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX, Flags.FLAG_SCENE_CONTAINER)
     @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
     fun testSwipeUp_communalEnabled_touchesNotSent() {
         kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
@@ -146,7 +190,11 @@
 
     // Verifies that a swipe up is not forwarded to the shade view.
     @Test
-    @DisableFlags(Flags.FLAG_COMMUNAL_HUB, Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
+    @DisableFlags(
+        Flags.FLAG_COMMUNAL_HUB,
+        Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX,
+        Flags.FLAG_SCENE_CONTAINER,
+    )
     fun testSwipeUp_communalDisabled_touchesNotSent() {
         swipe(Direction.UP)
 
@@ -155,6 +203,17 @@
         verify(mShadeViewController, never()).handleExternalTouch(any())
     }
 
+    // Verifies that a swipe up is not forwarded to the window root view.
+    @Test
+    @EnableFlags(Flags.FLAG_COMMUNAL_HUB, Flags.FLAG_SCENE_CONTAINER)
+    fun testSwipeUp_sceneContainerEnabled_touchesNotSent() {
+        swipe(Direction.UP)
+
+        // Motion events are not sent for window root view to process as the swipe is going in the
+        // wrong direction.
+        verify(windowRootView, never()).dispatchTouchEvent(any())
+    }
+
     @Test
     @DisableFlags(Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX)
     fun testCancelMotionEvent_popsTouchSession() {
@@ -243,10 +302,16 @@
 
     private enum class Direction {
         DOWN,
-        UP
+        UP,
     }
 
     companion object {
         private const val TOUCH_HEIGHT = 20
+
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return FlagsParameterization.allCombinationsOf().andSceneContainer()
+        }
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt
new file mode 100644
index 0000000..75a5768
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt
@@ -0,0 +1,127 @@
+/*
+ * 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.animation.back
+
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import android.view.animation.Interpolator
+import android.window.BackEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import com.android.app.animation.Interpolators
+import com.android.systemui.SysuiTestCase
+import com.android.window.flags.Flags.FLAG_PREDICTIVE_BACK_TIMESTAMP_API
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class FlingOnBackAnimationCallbackTest : SysuiTestCase() {
+
+    @get:Rule val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
+    @Test
+    fun testProgressInterpolation() {
+        val mockInterpolator = Mockito.mock(Interpolator::class.java)
+        val backEvent = backEventOf(0.5f)
+        Mockito.`when`(mockInterpolator.getInterpolation(0.5f)).thenReturn(0.8f)
+        val callback = TestFlingOnBackAnimationCallback(mockInterpolator)
+        callback.onBackStarted(backEvent)
+        assertTrue("Assert onBackStartedCompat called", callback.backStartedCalled)
+        callback.onBackProgressed(backEvent)
+        assertTrue("Assert onBackProgressedCompat called", callback.backProgressedCalled)
+        assertEquals("Assert interpolated progress", 0.8f, callback.progressEvent?.progress)
+    }
+
+    @Test
+    @RequiresFlagsEnabled(FLAG_PREDICTIVE_BACK_TIMESTAMP_API)
+    fun testFling() {
+        val callback = TestFlingOnBackAnimationCallback(Interpolators.LINEAR)
+        callback.onBackStarted(backEventOf(progress = 0f, frameTime = 0))
+        assertTrue("Assert onBackStartedCompat called", callback.backStartedCalled)
+        callback.onBackProgressed(backEventOf(0f, 8))
+        callback.onBackProgressed(backEventOf(0.2f, 16))
+        callback.onBackProgressed(backEventOf(0.4f, 24))
+        callback.onBackProgressed(backEventOf(0.6f, 32))
+        assertTrue("Assert onBackProgressedCompat called", callback.backProgressedCalled)
+        assertEquals("Assert interpolated progress", 0.6f, callback.progressEvent?.progress)
+        getInstrumentation().runOnMainSync { callback.onBackInvoked() }
+        // Assert that onBackInvoked is not called immediately...
+        assertFalse(callback.backInvokedCalled)
+        // Instead the fling animation is played and eventually onBackInvoked is called.
+        callback.backInvokedLatch.await(1000, TimeUnit.MILLISECONDS)
+        assertTrue(callback.backInvokedCalled)
+    }
+
+    @Test
+    @RequiresFlagsDisabled(FLAG_PREDICTIVE_BACK_TIMESTAMP_API)
+    fun testCallbackWithoutTimestampApi() {
+        // Assert that all callback methods are immediately forwarded
+        val callback = TestFlingOnBackAnimationCallback(Interpolators.LINEAR)
+        callback.onBackStarted(backEventOf(progress = 0f, frameTime = 0))
+        assertTrue("Assert onBackStartedCompat called", callback.backStartedCalled)
+        callback.onBackProgressed(backEventOf(0f, 8))
+        assertTrue("Assert onBackProgressedCompat called", callback.backProgressedCalled)
+        callback.onBackInvoked()
+        assertTrue("Assert onBackInvoked called", callback.backInvokedCalled)
+        callback.onBackCancelled()
+        assertTrue("Assert onBackCancelled called", callback.backCancelledCalled)
+    }
+
+    private fun backEventOf(progress: Float, frameTime: Long = 0): BackEvent {
+        return BackEvent(10f, 10f, progress, 0, frameTime)
+    }
+
+    /** Helper class to expose the compat functions for testing */
+    private class TestFlingOnBackAnimationCallback(progressInterpolator: Interpolator) :
+        FlingOnBackAnimationCallback(progressInterpolator) {
+        var backStartedCalled = false
+        var backProgressedCalled = false
+        var backInvokedCalled = false
+        val backInvokedLatch = CountDownLatch(1)
+        var backCancelledCalled = false
+        var progressEvent: BackEvent? = null
+
+        override fun onBackStartedCompat(backEvent: BackEvent) {
+            backStartedCalled = true
+        }
+
+        override fun onBackProgressedCompat(backEvent: BackEvent) {
+            backProgressedCalled = true
+            progressEvent = backEvent
+        }
+
+        override fun onBackInvokedCompat() {
+            backInvokedCalled = true
+            backInvokedLatch.countDown()
+        }
+
+        override fun onBackCancelledCompat() {
+            backCancelledCalled = true
+        }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
index e7d2ef1..21679f9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
@@ -187,7 +187,7 @@
                         signalCount = 1,
                         usageSessionStartTime = secondSignalReceivedTime,
                         userId = 0,
-                        gestureType = gestureType
+                        gestureType = gestureType,
                     )
                 )
         }
@@ -402,6 +402,29 @@
         eduClock.offset(initialDelayElapsedDuration)
     }
 
+    fun logMetricsForToastEducation() =
+        testScope.runTest {
+            triggerMaxEducationSignals(gestureType)
+            runCurrent()
+
+            verify(kosmos.mockEduMetricsLogger)
+                .logContextualEducationTriggered(gestureType, EducationUiType.Toast)
+        }
+
+    @Test
+    fun logMetricsForNotificationEducation() =
+        testScope.runTest {
+            triggerMaxEducationSignals(gestureType)
+            runCurrent()
+
+            eduClock.offset(minDurationForNextEdu)
+            triggerMaxEducationSignals(gestureType)
+            runCurrent()
+
+            verify(kosmos.mockEduMetricsLogger)
+                .logContextualEducationTriggered(gestureType, EducationUiType.Notification)
+        }
+
     @After
     fun clear() {
         testScope.launch { tutorialSchedulerRepository.clearDataStore() }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt
index 945f953..dbec350 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt
@@ -23,6 +23,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository
+import com.android.systemui.inputdevice.tutorial.inputDeviceTutorialLogger
 import com.android.systemui.inputdevice.tutorial.ui.TutorialNotificationCoordinator
 import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository
 import com.android.systemui.kosmos.Kosmos
@@ -75,16 +76,21 @@
             TutorialSchedulerRepository(
                 context,
                 dataStoreScope,
-                dataStoreName = "TutorialNotificationCoordinatorTest"
+                dataStoreName = "TutorialNotificationCoordinatorTest",
             )
         val interactor =
-            TutorialSchedulerInteractor(keyboardRepository, touchpadRepository, repository)
+            TutorialSchedulerInteractor(
+                keyboardRepository,
+                touchpadRepository,
+                repository,
+                kosmos.inputDeviceTutorialLogger,
+            )
         underTest =
             TutorialNotificationCoordinator(
                 testScope.backgroundScope,
                 context,
                 interactor,
-                notificationManager
+                notificationManager,
             )
         notificationCaptor = ArgumentCaptor.forClass(Notification::class.java)
         underTest.start()
@@ -103,7 +109,7 @@
             advanceTimeBy(LAUNCH_DELAY)
             verifyNotification(
                 R.string.launch_keyboard_tutorial_notification_title,
-                R.string.launch_keyboard_tutorial_notification_content
+                R.string.launch_keyboard_tutorial_notification_content,
             )
         }
 
@@ -114,7 +120,7 @@
             advanceTimeBy(LAUNCH_DELAY)
             verifyNotification(
                 R.string.launch_touchpad_tutorial_notification_title,
-                R.string.launch_touchpad_tutorial_notification_content
+                R.string.launch_touchpad_tutorial_notification_content,
             )
         }
 
@@ -126,7 +132,7 @@
             advanceTimeBy(LAUNCH_DELAY)
             verifyNotification(
                 R.string.launch_keyboard_touchpad_tutorial_notification_title,
-                R.string.launch_keyboard_touchpad_tutorial_notification_content
+                R.string.launch_keyboard_touchpad_tutorial_notification_content,
             )
         }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt
index 650f9dc..b0ffc47 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType
 import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository
 import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSchedulerInteractor.TutorialType
+import com.android.systemui.inputdevice.tutorial.inputDeviceTutorialLogger
 import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
@@ -62,10 +63,15 @@
             TutorialSchedulerRepository(
                 context,
                 dataStoreScope,
-                dataStoreName = "TutorialSchedulerInteractorTest"
+                dataStoreName = "TutorialSchedulerInteractorTest",
             )
         underTest =
-            TutorialSchedulerInteractor(keyboardRepository, touchpadRepository, schedulerRepository)
+            TutorialSchedulerInteractor(
+                keyboardRepository,
+                touchpadRepository,
+                schedulerRepository,
+                kosmos.inputDeviceTutorialLogger,
+            )
     }
 
     @After
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt
index 6e883c2..9e20e7d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyboard.shortcut.data.repository
 
 import android.hardware.input.fakeInputManager
+import android.view.KeyEvent.KEYCODE_1
 import android.view.KeyEvent.KEYCODE_A
 import android.view.KeyEvent.KEYCODE_B
 import android.view.KeyEvent.KEYCODE_C
@@ -24,6 +25,7 @@
 import android.view.KeyEvent.KEYCODE_E
 import android.view.KeyEvent.KEYCODE_F
 import android.view.KeyEvent.KEYCODE_G
+import android.view.KeyEvent.META_FUNCTION_ON
 import android.view.KeyboardShortcutGroup
 import android.view.KeyboardShortcutInfo
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -87,6 +89,48 @@
     }
 
     @Test
+    fun categories_keycodeAndModifiersAreMappedSeparatelyWhenIdentical() =
+        testScope.runTest {
+            fakeSystemSource.setGroups(simpleGroup(simpleShortcutInfo(KEYCODE_1)))
+
+            helper.toggle(deviceId = 123)
+            val categories by collectLastValue(repo.categories)
+
+            val systemCategory = categories?.firstOrNull { it.type == ShortcutCategoryType.System }
+
+            // Keycode 0x8 should be translated to the Key 1 instead of modifier FN
+            // which has the same keycode.
+            val expectedCategory =
+                ShortcutCategory(
+                    type = ShortcutCategoryType.System,
+                    simpleSubCategory(simpleShortcut("1")),
+                )
+
+            assertThat(systemCategory).isEqualTo(expectedCategory)
+        }
+
+    @Test
+    fun categories_keyCodeAndModifierHaveSameCode_codesAreMappedCorrectly() =
+        testScope.runTest {
+            fakeSystemSource.setGroups(simpleGroup(simpleShortcutInfo(KEYCODE_1, META_FUNCTION_ON)))
+
+            helper.toggle(deviceId = 123)
+            val categories by collectLastValue(repo.categories)
+
+            val systemCategory = categories?.firstOrNull { it.type == ShortcutCategoryType.System }
+
+            // Keycode 0x8 should be translated to the Key 1 instead of modifier FN
+            // which has the same keycode. while modifier mask 0x8 should be translated to FN.
+            val expectedCategory =
+                ShortcutCategory(
+                    type = ShortcutCategoryType.System,
+                    simpleSubCategory(simpleShortcut("Fn", "1")),
+                )
+
+            assertThat(systemCategory).isEqualTo(expectedCategory)
+        }
+
+    @Test
     fun categories_multipleSubscribers_replaysExistingValueToNewSubscribers() =
         testScope.runTest {
             fakeSystemSource.setGroups(TestShortcuts.systemGroups)
@@ -111,24 +155,14 @@
         testScope.runTest {
             fakeSystemSource.setGroups(
                 listOf(
-                    simpleGroup(
-                        simpleShortcutInfo(KEYCODE_A),
-                        simpleShortcutInfo(KEYCODE_B),
-                    ),
-                    simpleGroup(
-                        simpleShortcutInfo(KEYCODE_C),
-                    ),
+                    simpleGroup(simpleShortcutInfo(KEYCODE_A), simpleShortcutInfo(KEYCODE_B)),
+                    simpleGroup(simpleShortcutInfo(KEYCODE_C)),
                 )
             )
             fakeMultiTaskingSource.setGroups(
                 listOf(
-                    simpleGroup(
-                        simpleShortcutInfo(KEYCODE_D),
-                    ),
-                    simpleGroup(
-                        simpleShortcutInfo(KEYCODE_E),
-                        simpleShortcutInfo(KEYCODE_F),
-                    ),
+                    simpleGroup(simpleShortcutInfo(KEYCODE_D)),
+                    simpleGroup(simpleShortcutInfo(KEYCODE_E), simpleShortcutInfo(KEYCODE_F)),
                 )
             )
             fakeAppCategoriesSource.setGroups(listOf(simpleGroup(simpleShortcutInfo(KEYCODE_G))))
@@ -144,16 +178,11 @@
                         listOf(
                             simpleSubCategory(simpleShortcut("B")),
                             simpleSubCategory(simpleShortcut("C")),
-                        )
+                        ),
                     ),
                     ShortcutCategory(
                         ShortcutCategoryType.MultiTasking,
-                        listOf(
-                            simpleSubCategory(
-                                simpleShortcut("E"),
-                                simpleShortcut("F"),
-                            ),
-                        )
+                        listOf(simpleSubCategory(simpleShortcut("E"), simpleShortcut("F"))),
                     ),
                 )
         }
@@ -164,14 +193,14 @@
     private fun simpleShortcut(vararg keys: String) =
         Shortcut(
             label = simpleShortcutLabel,
-            commands = listOf(ShortcutCommand(keys.map { ShortcutKey.Text(it) }))
+            commands = listOf(ShortcutCommand(keys.map { ShortcutKey.Text(it) })),
         )
 
     private fun simpleGroup(vararg shortcuts: KeyboardShortcutInfo) =
         KeyboardShortcutGroup(simpleGroupLabel, shortcuts.asList())
 
-    private fun simpleShortcutInfo(keyCode: Int = 0) =
-        KeyboardShortcutInfo(simpleShortcutLabel, keyCode, /* modifiers= */ 0)
+    private fun simpleShortcutInfo(keyCode: Int = 0, modifiers: Int = 0) =
+        KeyboardShortcutInfo(simpleShortcutLabel, keyCode, modifiers)
 
     private val simpleShortcutLabel = "shortcut label"
     private val simpleGroupLabel = "group label"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
index eae6cdb..d921dde 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
@@ -35,44 +35,30 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class TaskbarDelegateTest : SysuiTestCase() {
-    val DISPLAY_ID = 0;
-    val MODE_GESTURE = 0;
-    val MODE_THREE_BUTTON = 1;
+    val DISPLAY_ID = 0
+
+    val MODE_GESTURE = 0
+
+    val MODE_THREE_BUTTON = 1
 
     private lateinit var mTaskStackChangeListeners: TaskStackChangeListeners
     private lateinit var mTaskbarDelegate: TaskbarDelegate
-    @Mock
-    lateinit var mEdgeBackGestureHandler : EdgeBackGestureHandler
-    @Mock
-    lateinit var mLightBarControllerFactory : LightBarTransitionsController.Factory
-    @Mock
-    lateinit var mLightBarTransitionController: LightBarTransitionsController
-    @Mock
-    lateinit var mCommandQueue: CommandQueue
-    @Mock
-    lateinit var mOverviewProxyService: OverviewProxyService
-    @Mock
-    lateinit var mNavBarHelper: NavBarHelper
-    @Mock
-    lateinit var mNavigationModeController: NavigationModeController
-    @Mock
-    lateinit var mSysUiState: SysUiState
-    @Mock
-    lateinit var mDumpManager: DumpManager
-    @Mock
-    lateinit var mAutoHideController: AutoHideController
-    @Mock
-    lateinit var mLightBarController: LightBarController
-    @Mock
-    lateinit var mOptionalPip: Optional<Pip>
-    @Mock
-    lateinit var mBackAnimation: BackAnimation
-    @Mock
-    lateinit var mCurrentSysUiState: NavBarHelper.CurrentSysuiState
-    @Mock
-    lateinit var mStatusBarKeyguardViewManager: StatusBarKeyguardViewManager
-    @Mock
-    lateinit var mStatusBarStateController: StatusBarStateController
+    @Mock lateinit var mEdgeBackGestureHandler: EdgeBackGestureHandler
+    @Mock lateinit var mLightBarControllerFactory: LightBarTransitionsController.Factory
+    @Mock lateinit var mLightBarTransitionController: LightBarTransitionsController
+    @Mock lateinit var mCommandQueue: CommandQueue
+    @Mock lateinit var mOverviewProxyService: OverviewProxyService
+    @Mock lateinit var mNavBarHelper: NavBarHelper
+    @Mock lateinit var mNavigationModeController: NavigationModeController
+    @Mock lateinit var mSysUiState: SysUiState
+    @Mock lateinit var mDumpManager: DumpManager
+    @Mock lateinit var mAutoHideController: AutoHideController
+    @Mock lateinit var mLightBarController: LightBarController
+    @Mock lateinit var mOptionalPip: Optional<Pip>
+    @Mock lateinit var mBackAnimation: BackAnimation
+    @Mock lateinit var mCurrentSysUiState: NavBarHelper.CurrentSysuiState
+    @Mock lateinit var mStatusBarKeyguardViewManager: StatusBarKeyguardViewManager
+    @Mock lateinit var mStatusBarStateController: StatusBarStateController
 
     @Before
     fun setup() {
@@ -82,11 +68,26 @@
         `when`(mNavBarHelper.currentSysuiState).thenReturn(mCurrentSysUiState)
         `when`(mSysUiState.setFlag(anyLong(), anyBoolean())).thenReturn(mSysUiState)
         mTaskStackChangeListeners = TaskStackChangeListeners.getTestInstance()
-        mTaskbarDelegate = TaskbarDelegate(context, mLightBarControllerFactory,
-            mStatusBarKeyguardViewManager, mStatusBarStateController)
-        mTaskbarDelegate.setDependencies(mCommandQueue, mOverviewProxyService, mNavBarHelper,
-        mNavigationModeController, mSysUiState, mDumpManager, mAutoHideController,
-                mLightBarController, mOptionalPip, mBackAnimation, mTaskStackChangeListeners)
+        mTaskbarDelegate =
+            TaskbarDelegate(
+                context,
+                mLightBarControllerFactory,
+                mStatusBarKeyguardViewManager,
+                mStatusBarStateController,
+            )
+        mTaskbarDelegate.setDependencies(
+            mCommandQueue,
+            mOverviewProxyService,
+            mNavBarHelper,
+            mNavigationModeController,
+            mSysUiState,
+            mDumpManager,
+            mAutoHideController,
+            mLightBarController,
+            mOptionalPip,
+            mBackAnimation,
+            mTaskStackChangeListeners,
+        )
     }
 
     @Test
@@ -108,10 +109,12 @@
     fun screenPinningEnabled_updatesSysuiState() {
         mTaskbarDelegate.init(DISPLAY_ID)
         mTaskStackChangeListeners.listenerImpl.onLockTaskModeChanged(
-            ActivityManager.LOCK_TASK_MODE_PINNED)
-        verify(mSysUiState, times(1)).setFlag(
-            ArgumentMatchers.eq(QuickStepContract.SYSUI_STATE_SCREEN_PINNING),
-            ArgumentMatchers.eq(true)
+            ActivityManager.LOCK_TASK_MODE_PINNED
         )
+        verify(mSysUiState, times(1))
+            .setFlag(
+                ArgumentMatchers.eq(QuickStepContract.SYSUI_STATE_SCREEN_PINNING),
+                ArgumentMatchers.eq(true),
+            )
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt
index f3cea3e..a64eda7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt
@@ -8,24 +8,23 @@
 import com.android.systemui.shared.rotation.FloatingRotationButtonPositionCalculator.Position
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4
-import platform.test.runner.parameterized.Parameter
-import platform.test.runner.parameterized.Parameters
 import org.junit.runner.RunWith
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @RunWith(ParameterizedAndroidJunit4::class)
 @SmallTest
-internal class FloatingRotationButtonPositionCalculatorTest(
-        private val testCase: TestCase,
-) : SysuiTestCase() {
+internal class FloatingRotationButtonPositionCalculatorTest(private val testCase: TestCase) :
+    SysuiTestCase() {
 
     @Test
     fun calculatePosition() {
-        val position = testCase.calculator.calculatePosition(
-            testCase.rotation,
-            testCase.taskbarVisible,
-            testCase.taskbarStashed
-        )
+        val position =
+            testCase.calculator.calculatePosition(
+                testCase.rotation,
+                testCase.taskbarVisible,
+                testCase.taskbarStashed,
+            )
         assertThat(position).isEqualTo(testCase.expectedPosition)
     }
 
@@ -34,21 +33,22 @@
         val rotation: Int,
         val taskbarVisible: Boolean,
         val taskbarStashed: Boolean,
-        val expectedPosition: Position
+        val expectedPosition: Position,
     ) {
-        override fun toString(): String =
-                buildString {
-                    append("when calculator = ")
-                    append(when (calculator) {
-                        posLeftCalculator -> "LEFT"
-                        posRightCalculator -> "RIGHT"
-                        else -> error("Unknown calculator: $calculator")
-                    })
-                    append(", rotation = $rotation")
-                    append(", taskbarVisible = $taskbarVisible")
-                    append(", taskbarStashed = $taskbarStashed")
-                    append(" - expected $expectedPosition")
+        override fun toString(): String = buildString {
+            append("when calculator = ")
+            append(
+                when (calculator) {
+                    posLeftCalculator -> "LEFT"
+                    posRightCalculator -> "RIGHT"
+                    else -> error("Unknown calculator: $calculator")
                 }
+            )
+            append(", rotation = $rotation")
+            append(", taskbarVisible = $taskbarVisible")
+            append(", taskbarStashed = $taskbarStashed")
+            append(" - expected $expectedPosition")
+        }
     }
 
     companion object {
@@ -56,12 +56,20 @@
         private const val MARGIN_TASKBAR_LEFT = 20
         private const val MARGIN_TASKBAR_BOTTOM = 30
 
-        private val posLeftCalculator = FloatingRotationButtonPositionCalculator(
-            MARGIN_DEFAULT, MARGIN_TASKBAR_LEFT, MARGIN_TASKBAR_BOTTOM, true
-        )
-        private val posRightCalculator = FloatingRotationButtonPositionCalculator(
-            MARGIN_DEFAULT, MARGIN_TASKBAR_LEFT, MARGIN_TASKBAR_BOTTOM, false
-        )
+        private val posLeftCalculator =
+            FloatingRotationButtonPositionCalculator(
+                MARGIN_DEFAULT,
+                MARGIN_TASKBAR_LEFT,
+                MARGIN_TASKBAR_BOTTOM,
+                true,
+            )
+        private val posRightCalculator =
+            FloatingRotationButtonPositionCalculator(
+                MARGIN_DEFAULT,
+                MARGIN_TASKBAR_LEFT,
+                MARGIN_TASKBAR_BOTTOM,
+                false,
+            )
 
         @Parameters(name = "{0}")
         @JvmStatic
@@ -73,77 +81,84 @@
                     rotation = Surface.ROTATION_0,
                     taskbarVisible = false,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.BOTTOM or Gravity.LEFT,
-                        translationX = MARGIN_DEFAULT,
-                        translationY = -MARGIN_DEFAULT
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.BOTTOM or Gravity.LEFT,
+                            translationX = MARGIN_DEFAULT,
+                            translationY = -MARGIN_DEFAULT,
+                        ),
                 ),
                 TestCase(
                     calculator = posLeftCalculator,
                     rotation = Surface.ROTATION_90,
                     taskbarVisible = false,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.BOTTOM or Gravity.RIGHT,
-                        translationX = -MARGIN_DEFAULT,
-                        translationY = -MARGIN_DEFAULT
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.BOTTOM or Gravity.RIGHT,
+                            translationX = -MARGIN_DEFAULT,
+                            translationY = -MARGIN_DEFAULT,
+                        ),
                 ),
                 TestCase(
                     calculator = posLeftCalculator,
                     rotation = Surface.ROTATION_180,
                     taskbarVisible = false,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.TOP or Gravity.RIGHT,
-                        translationX = -MARGIN_DEFAULT,
-                        translationY = MARGIN_DEFAULT
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.TOP or Gravity.RIGHT,
+                            translationX = -MARGIN_DEFAULT,
+                            translationY = MARGIN_DEFAULT,
+                        ),
                 ),
                 TestCase(
                     calculator = posLeftCalculator,
                     rotation = Surface.ROTATION_270,
                     taskbarVisible = false,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.TOP or Gravity.LEFT,
-                        translationX = MARGIN_DEFAULT,
-                        translationY = MARGIN_DEFAULT
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.TOP or Gravity.LEFT,
+                            translationX = MARGIN_DEFAULT,
+                            translationY = MARGIN_DEFAULT,
+                        ),
                 ),
                 TestCase(
                     calculator = posLeftCalculator,
                     rotation = Surface.ROTATION_0,
                     taskbarVisible = true,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.BOTTOM or Gravity.LEFT,
-                        translationX = MARGIN_TASKBAR_LEFT,
-                        translationY = -MARGIN_TASKBAR_BOTTOM
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.BOTTOM or Gravity.LEFT,
+                            translationX = MARGIN_TASKBAR_LEFT,
+                            translationY = -MARGIN_TASKBAR_BOTTOM,
+                        ),
                 ),
                 TestCase(
                     calculator = posLeftCalculator,
                     rotation = Surface.ROTATION_0,
                     taskbarVisible = true,
                     taskbarStashed = true,
-                    expectedPosition = Position(
-                        gravity = Gravity.BOTTOM or Gravity.LEFT,
-                        translationX = MARGIN_DEFAULT,
-                        translationY = -MARGIN_DEFAULT
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.BOTTOM or Gravity.LEFT,
+                            translationX = MARGIN_DEFAULT,
+                            translationY = -MARGIN_DEFAULT,
+                        ),
                 ),
                 TestCase(
                     calculator = posLeftCalculator,
                     rotation = Surface.ROTATION_90,
                     taskbarVisible = true,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.BOTTOM or Gravity.RIGHT,
-                        translationX = -MARGIN_TASKBAR_LEFT,
-                        translationY = -MARGIN_TASKBAR_BOTTOM
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.BOTTOM or Gravity.RIGHT,
+                            translationX = -MARGIN_TASKBAR_LEFT,
+                            translationY = -MARGIN_TASKBAR_BOTTOM,
+                        ),
                 ),
 
                 // Position right
@@ -152,78 +167,85 @@
                     rotation = Surface.ROTATION_0,
                     taskbarVisible = false,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.BOTTOM or Gravity.RIGHT,
-                        translationX = -MARGIN_DEFAULT,
-                        translationY = -MARGIN_DEFAULT
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.BOTTOM or Gravity.RIGHT,
+                            translationX = -MARGIN_DEFAULT,
+                            translationY = -MARGIN_DEFAULT,
+                        ),
                 ),
                 TestCase(
                     calculator = posRightCalculator,
                     rotation = Surface.ROTATION_90,
                     taskbarVisible = false,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.TOP or Gravity.RIGHT,
-                        translationX = -MARGIN_DEFAULT,
-                        translationY = MARGIN_DEFAULT
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.TOP or Gravity.RIGHT,
+                            translationX = -MARGIN_DEFAULT,
+                            translationY = MARGIN_DEFAULT,
+                        ),
                 ),
                 TestCase(
                     calculator = posRightCalculator,
                     rotation = Surface.ROTATION_180,
                     taskbarVisible = false,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.TOP or Gravity.LEFT,
-                        translationX = MARGIN_DEFAULT,
-                        translationY = MARGIN_DEFAULT
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.TOP or Gravity.LEFT,
+                            translationX = MARGIN_DEFAULT,
+                            translationY = MARGIN_DEFAULT,
+                        ),
                 ),
                 TestCase(
                     calculator = posRightCalculator,
                     rotation = Surface.ROTATION_270,
                     taskbarVisible = false,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.BOTTOM or Gravity.LEFT,
-                        translationX = MARGIN_DEFAULT,
-                        translationY = -MARGIN_DEFAULT
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.BOTTOM or Gravity.LEFT,
+                            translationX = MARGIN_DEFAULT,
+                            translationY = -MARGIN_DEFAULT,
+                        ),
                 ),
                 TestCase(
                     calculator = posRightCalculator,
                     rotation = Surface.ROTATION_0,
                     taskbarVisible = true,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.BOTTOM or Gravity.RIGHT,
-                        translationX = -MARGIN_TASKBAR_LEFT,
-                        translationY = -MARGIN_TASKBAR_BOTTOM
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.BOTTOM or Gravity.RIGHT,
+                            translationX = -MARGIN_TASKBAR_LEFT,
+                            translationY = -MARGIN_TASKBAR_BOTTOM,
+                        ),
                 ),
                 TestCase(
                     calculator = posRightCalculator,
                     rotation = Surface.ROTATION_0,
                     taskbarVisible = true,
                     taskbarStashed = true,
-                    expectedPosition = Position(
-                        gravity = Gravity.BOTTOM or Gravity.RIGHT,
-                        translationX = -MARGIN_DEFAULT,
-                        translationY = -MARGIN_DEFAULT
-                    )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.BOTTOM or Gravity.RIGHT,
+                            translationX = -MARGIN_DEFAULT,
+                            translationY = -MARGIN_DEFAULT,
+                        ),
                 ),
                 TestCase(
                     calculator = posRightCalculator,
                     rotation = Surface.ROTATION_90,
                     taskbarVisible = true,
                     taskbarStashed = false,
-                    expectedPosition = Position(
-                        gravity = Gravity.TOP or Gravity.RIGHT,
-                        translationX = -MARGIN_TASKBAR_LEFT,
-                        translationY = MARGIN_TASKBAR_BOTTOM
-                    )
-                )
+                    expectedPosition =
+                        Position(
+                            gravity = Gravity.TOP or Gravity.RIGHT,
+                            translationX = -MARGIN_TASKBAR_LEFT,
+                            translationY = MARGIN_TASKBAR_BOTTOM,
+                        ),
+                ),
             )
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt
deleted file mode 100644
index 7ad904e..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt
+++ /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 com.android.systemui.qs.panels.domain.interactor
-
-import android.content.pm.UserInfo
-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.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.Test
-import org.junit.runner.RunWith
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class IconLabelVisibilityInteractorTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
-    private val underTest = with(kosmos) { iconLabelVisibilityInteractor }
-
-    @Before
-    fun setUp() {
-        with(kosmos) { fakeUserRepository.setUserInfos(USERS) }
-    }
-
-    @Test
-    fun changingShowLabels_receivesCorrectShowLabels() =
-        with(kosmos) {
-            testScope.runTest {
-                val showLabels by collectLastValue(underTest.showLabels)
-
-                underTest.setShowLabels(false)
-                runCurrent()
-                assertThat(showLabels).isFalse()
-
-                underTest.setShowLabels(true)
-                runCurrent()
-                assertThat(showLabels).isTrue()
-            }
-        }
-
-    @Test
-    fun changingUser_receivesCorrectShowLabels() =
-        with(kosmos) {
-            testScope.runTest {
-                val showLabels by collectLastValue(underTest.showLabels)
-
-                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
-                underTest.setShowLabels(false)
-                runCurrent()
-                assertThat(showLabels).isFalse()
-
-                fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
-                underTest.setShowLabels(true)
-                runCurrent()
-                assertThat(showLabels).isTrue()
-
-                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
-                runCurrent()
-                assertThat(showLabels).isFalse()
-            }
-        }
-
-    companion object {
-        private val PRIMARY_USER = UserInfo(0, "user 0", UserInfo.FLAG_MAIN)
-        private val ANOTHER_USER = UserInfo(1, "user 1", UserInfo.FLAG_FULL)
-        private val USERS = listOf(PRIMARY_USER, ANOTHER_USER)
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt
index 5bd3645..99d2da67 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt
@@ -30,9 +30,11 @@
 import com.android.systemui.qs.pipeline.domain.interactor.panelInteractor
 import com.android.systemui.qs.tiles.base.interactor.QSTileInput
 import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.recordissue.IssueRecordingState
 import com.android.systemui.recordissue.RecordIssueDialogDelegate
 import com.android.systemui.screenrecord.RecordingController
 import com.android.systemui.settings.UserContextProvider
+import com.android.systemui.settings.userFileManager
 import com.android.systemui.settings.userTracker
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil
 import com.android.systemui.statusbar.policy.keyguardStateController
@@ -81,10 +83,11 @@
             underTest =
                 IssueRecordingUserActionInteractor(
                     testDispatcher,
+                    IssueRecordingState(userTracker, userFileManager),
                     KeyguardDismissUtil(
                         keyguardStateController,
                         statusBarStateController,
-                        activityStarter
+                        activityStarter,
                     ),
                     keyguardStateController,
                     dialogTransitionAnimator,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt
index a1edfc1..aceaab8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt
@@ -60,6 +60,7 @@
     private val iActivityManager = mock<IActivityManager>()
     private val notificationManager = mock<NotificationManager>()
     private val panelInteractor = mock<PanelInteractor>()
+    private val screenRecordingStartTimeStore = mock<ScreenRecordingStartTimeStore>()
 
     private lateinit var underTest: IssueRecordingServiceSession
 
@@ -76,6 +77,7 @@
                 iActivityManager,
                 notificationManager,
                 userContextProvider,
+                screenRecordingStartTimeStore,
             )
     }
 
@@ -90,7 +92,7 @@
 
     @Test
     fun stopsTracing_afterReceivingStopTracingCommand() {
-        underTest.stop(mContext.contentResolver)
+        underTest.stop()
         bgExecutor.runAllReady()
 
         Truth.assertThat(issueRecordingState.isRecording).isFalse()
@@ -107,24 +109,24 @@
 
     @Test
     fun requestBugreport_afterReceivingShareCommand_withTakeBugreportTrue() {
-        issueRecordingState.takeBugreport = true
+        underTest.takeBugReport = true
         val uri = mock<Uri>()
 
         underTest.share(0, uri)
         bgExecutor.runAllReady()
 
-        verify(iActivityManager).requestBugReportWithExtraAttachment(uri)
+        verify(iActivityManager).requestBugReportWithExtraAttachments(any())
     }
 
     @Test
     fun sharesTracesDirectly_afterReceivingShareCommand_withTakeBugreportFalse() {
-        issueRecordingState.takeBugreport = false
+        underTest.takeBugReport = false
         val uri = mock<Uri>()
 
         underTest.share(0, uri)
         bgExecutor.runAllReady()
 
-        verify(traceurConnection).shareTraces(uri)
+        verify(traceurConnection).shareTraces(any())
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStoreTest.kt
new file mode 100644
index 0000000..737b101
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStoreTest.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.recordissue
+
+import android.testing.TestableLooper
+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.testCase
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.settings.userTracker
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class ScreenRecordingStartTimeStoreTest : SysuiTestCase() {
+    private val userTracker: UserTracker = Kosmos().also { it.testCase = this }.userTracker
+
+    private lateinit var underTest: ScreenRecordingStartTimeStore
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        underTest = ScreenRecordingStartTimeStore(userTracker)
+    }
+
+    @Test
+    fun markStartTime_correctlyStoresValues_inSharedPreferences() {
+        underTest.markStartTime()
+
+        val startTimeMetadata = underTest.userIdToScreenRecordingStartTime.get(userTracker.userId)
+        Truth.assertThat(startTimeMetadata).isNotNull()
+        Truth.assertThat(startTimeMetadata!!.getLong(ELAPSED_REAL_TIME_NANOS_KEY)).isNotNull()
+        Truth.assertThat(startTimeMetadata.getLong(REAL_TO_ELAPSED_TIME_OFFSET_NANOS_KEY))
+            .isNotNull()
+    }
+}
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 0d5ddae..bff3903 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
@@ -52,6 +52,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.recordissue.ScreenRecordingStartTimeStore;
 import com.android.systemui.settings.UserContextProvider;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
@@ -95,6 +96,8 @@
     private SysuiStatusBarStateController mStatusBarStateController;
     @Mock
     private ActivityStarter mActivityStarter;
+    @Mock
+    private ScreenRecordingStartTimeStore mScreenRecordingStartTimeStore;
 
     private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
 
@@ -108,9 +111,10 @@
                 RecordingController controller, Executor executor,
                 Handler handler, UiEventLogger uiEventLogger,
                 NotificationManager notificationManager,
-                UserContextProvider userContextTracker, KeyguardDismissUtil keyguardDismissUtil) {
-            super(controller, executor, handler,
-                    uiEventLogger, notificationManager, userContextTracker, keyguardDismissUtil);
+                UserContextProvider userContextTracker, KeyguardDismissUtil keyguardDismissUtil,
+                ScreenRecordingStartTimeStore screenRecordingStartTimeStore) {
+            super(controller, executor, handler, uiEventLogger, notificationManager,
+                    userContextTracker, keyguardDismissUtil, screenRecordingStartTimeStore);
             attachBaseContext(mContext);
         }
     }
@@ -120,7 +124,7 @@
         MockitoAnnotations.initMocks(this);
         mRecordingService = Mockito.spy(new RecordingServiceTestable(mController, mExecutor,
                 mHandler, mUiEventLogger, mNotificationManager,
-                mUserContextTracker, mKeyguardDismissUtil));
+                mUserContextTracker, mKeyguardDismissUtil, mScreenRecordingStartTimeStore));
 
         // Return actual context info
         doReturn(mContext).when(mRecordingService).getApplicationContext();
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/ScrollCaptureControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/ScrollCaptureControllerTest.java
index f8de714..a831e63 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/ScrollCaptureControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/scroll/ScrollCaptureControllerTest.java
@@ -38,6 +38,8 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.screenshot.scroll.ScrollCaptureClient.Session;
 
+import org.junit.Assume;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -49,6 +51,12 @@
 @RunWith(AndroidJUnit4.class)
 public class ScrollCaptureControllerTest extends SysuiTestCase {
 
+    @Before
+    public void assumeOnDevice() {
+        // TODO(b/373930957) this class hangs under robolectric
+        Assume.assumeFalse(isRobolectricTest());
+    }
+
     private static final ScrollCaptureResponse EMPTY_RESPONSE =
             new ScrollCaptureResponse.Builder().build();
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index d1d3b9b..89ad699 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -85,7 +85,6 @@
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.classifier.FalsingCollectorFake;
 import com.android.systemui.classifier.FalsingManagerFake;
-import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository;
 import com.android.systemui.common.ui.view.LongPressHandlingView;
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor;
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor;
@@ -434,15 +433,6 @@
                 new ShadeInteractorLegacyImpl(
                         mTestScope.getBackgroundScope(),
                         mFakeKeyguardRepository,
-                        new SharedNotificationContainerInteractor(
-                                new FakeConfigurationRepository(),
-                                mContext,
-                                () -> splitShadeStateController,
-                                () -> mShadeInteractor,
-                                mKeyguardInteractor,
-                                deviceEntryUdfpsInteractor,
-                                () -> mLargeScreenHeaderHelper
-                        ),
                         mShadeRepository
                 ),
                 mKosmos.getShadeModeInteractor());
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
index f38bf13..ab5fa8e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
@@ -6,12 +6,11 @@
 import android.view.DisplayCutout
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.battery.BatteryMeterView
-import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.data.repository.fakeStatusBarContentInsetsProviderStore
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Rule
@@ -19,6 +18,8 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.junit.MockitoJUnit
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -35,9 +36,12 @@
         const val QS_END_FRAME = 58
     }
 
+    private val kosmos = testKosmos()
+    private val insetsProviderStore = kosmos.fakeStatusBarContentInsetsProviderStore
+    private val insetsProvider = insetsProviderStore.defaultDisplay
+
     @JvmField @Rule val mockitoRule = MockitoJUnit.rule()!!
 
-    @Mock private lateinit var insetsProvider: StatusBarContentInsetsProvider
     @Mock private lateinit var mockedContext: Context
     @Mock private lateinit var mockedResources: Resources
 
@@ -49,8 +53,7 @@
         whenever(mockedResources.getInteger(R.integer.fade_in_start_frame)).thenReturn(QS_END_FRAME)
         whenever(mockedResources.getInteger(R.integer.fade_out_complete_frame))
             .thenReturn(QQS_START_FRAME)
-
-        controller = QsBatteryModeController(mockedContext, insetsProvider)
+        controller = QsBatteryModeController(mockedContext, insetsProviderStore)
     }
 
     @Test
@@ -96,5 +99,6 @@
     }
 
     private fun Int.prevFrameToFraction(): Float = (this - 1) / MOTION_LAYOUT_MAX_FRAME.toFloat()
+
     private fun Int.nextFrameToFraction(): Float = (this + 1) / MOTION_LAYOUT_MAX_FRAME.toFloat()
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
index a52f173..2e759a3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
@@ -36,16 +36,12 @@
 import com.android.keyguard.KeyguardStatusView;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository;
-import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository;
-import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor;
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor;
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
 import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.media.controls.domain.pipeline.MediaDataManager;
@@ -55,7 +51,6 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor;
 import com.android.systemui.qs.QSFragmentLegacy;
 import com.android.systemui.res.R;
-import com.android.systemui.scene.domain.interactor.SceneInteractor;
 import com.android.systemui.screenrecord.RecordingController;
 import com.android.systemui.shade.data.repository.FakeShadeRepository;
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
@@ -72,7 +67,6 @@
 import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor;
 import com.android.systemui.statusbar.notification.stack.AmbientState;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -179,27 +173,11 @@
         mStatusBarStateController = mKosmos.getStatusBarStateController();
 
         mKosmos.getFakeDeviceProvisioningRepository().setDeviceProvisioned(true);
-        FakeConfigurationRepository configurationRepository = new FakeConfigurationRepository();
 
         PowerInteractor powerInteractor = mKosmos.getPowerInteractor();
 
-        SceneInteractor sceneInteractor = mKosmos.getSceneInteractor();
-
         KeyguardTransitionInteractor keyguardTransitionInteractor =
                 mKosmos.getKeyguardTransitionInteractor();
-        KeyguardInteractor keyguardInteractor = new KeyguardInteractor(
-                mKeyguardRepository,
-                powerInteractor,
-                new FakeKeyguardBouncerRepository(),
-                new ConfigurationInteractor(configurationRepository),
-                mShadeRepository,
-                keyguardTransitionInteractor,
-                () -> sceneInteractor,
-                () -> mKosmos.getFromGoneTransitionInteractor(),
-                () -> mKosmos.getFromLockscreenTransitionInteractor(),
-                () -> mKosmos.getFromOccludedTransitionInteractor(),
-                () -> mKosmos.getSharedNotificationContainerInteractor(),
-                mTestScope);
 
         ResourcesSplitShadeStateController splitShadeStateController =
                 new ResourcesSplitShadeStateController();
@@ -222,14 +200,6 @@
                 new ShadeInteractorLegacyImpl(
                         mTestScope.getBackgroundScope(),
                         mKeyguardRepository,
-                        new SharedNotificationContainerInteractor(
-                                configurationRepository,
-                                mContext,
-                                () -> splitShadeStateController,
-                                () -> mShadeInteractor,
-                                keyguardInteractor,
-                                deviceEntryUdfpsInteractor,
-                                () -> mLargeScreenHeaderHelper),
                         mShadeRepository
                 ),
                 mKosmos.getShadeModeInteractor());
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImplTest.kt
index 4592b60..238a1c1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImplTest.kt
@@ -26,9 +26,9 @@
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.shade.data.repository.fakeShadeRepository
+import com.android.systemui.shade.shadeTestUtil
 import com.android.systemui.testKosmos
 import com.android.systemui.user.data.repository.fakeUserRepository
 import com.google.common.truth.Truth.assertThat
@@ -46,6 +46,7 @@
 class ShadeInteractorLegacyImplTest : SysuiTestCase() {
     val kosmos = testKosmos()
     val testScope = kosmos.testScope
+    val shadeTestUtil = kosmos.shadeTestUtil
     val configurationRepository = kosmos.fakeConfigurationRepository
     val keyguardRepository = kosmos.fakeKeyguardRepository
     val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
@@ -87,7 +88,7 @@
 
             // WHEN split shade is enabled and QS is expanded
             keyguardRepository.setStatusBarState(StatusBarState.SHADE)
-            overrideResource(R.bool.config_use_split_notification_shade, true)
+            shadeTestUtil.setSplitShade(true)
             configurationRepository.onAnyConfigurationChange()
             shadeRepository.setQsExpansion(.5f)
             shadeRepository.setLegacyShadeExpansion(.7f)
@@ -104,7 +105,7 @@
 
             // WHEN split shade is not enabled and QS is expanded
             keyguardRepository.setStatusBarState(StatusBarState.SHADE)
-            overrideResource(R.bool.config_use_split_notification_shade, false)
+            shadeTestUtil.setSplitShade(false)
             shadeRepository.setQsExpansion(.5f)
             shadeRepository.setLegacyShadeExpansion(1f)
             runCurrent()
@@ -120,7 +121,7 @@
 
             // WHEN split shade is not enabled and QS is expanded
             keyguardRepository.setStatusBarState(StatusBarState.SHADE)
-            overrideResource(R.bool.config_use_split_notification_shade, false)
+            shadeTestUtil.setSplitShade(false)
             shadeRepository.setQsExpansion(1f)
             shadeRepository.setLegacyShadeExpansion(1f)
             runCurrent()
@@ -136,7 +137,7 @@
 
             // WHEN split shade is not enabled and QS partly expanded
             keyguardRepository.setStatusBarState(StatusBarState.SHADE)
-            overrideResource(R.bool.config_use_split_notification_shade, false)
+            shadeTestUtil.setSplitShade(false)
             shadeRepository.setQsExpansion(.4f)
             shadeRepository.setLegacyShadeExpansion(1f)
             runCurrent()
@@ -152,7 +153,7 @@
 
             // WHEN split shade is not enabled and QS collapsed
             keyguardRepository.setStatusBarState(StatusBarState.SHADE)
-            overrideResource(R.bool.config_use_split_notification_shade, false)
+            shadeTestUtil.setSplitShade(false)
             shadeRepository.setQsExpansion(0f)
             shadeRepository.setLegacyShadeExpansion(.6f)
             runCurrent()
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
new file mode 100644
index 0000000..0eebab0
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.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.systemui.statusbar.data.repository
+
+import android.view.Display.DEFAULT_DISPLAY
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.unconfinedTestDispatcher
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class MultiDisplayStatusBarContentInsetsProviderStoreTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos().also { it.testDispatcher = it.unconfinedTestDispatcher }
+    private val testScope = kosmos.testScope
+    private val fakeDisplayRepository = kosmos.displayRepository
+    private val underTest = kosmos.multiDisplayStatusBarContentInsetsProviderStore
+
+    @Before
+    fun start() {
+        underTest.start()
+    }
+
+    @Before fun addDisplays() = runBlocking { fakeDisplayRepository.addDisplay(DEFAULT_DISPLAY) }
+
+    @Test
+    fun forDisplay_startsInstances() =
+        testScope.runTest {
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+
+            verify(instance).start()
+        }
+
+    @Test
+    fun beforeDisplayRemoved_doesNotStopInstances() =
+        testScope.runTest {
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+
+            verify(instance, never()).stop()
+        }
+
+    @Test
+    fun displayRemoved_stopsInstance() =
+        testScope.runTest {
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+
+            fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+
+            verify(instance).stop()
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationScrimNestedScrollConnectionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationScrimNestedScrollConnectionTest.kt
index 1f1680e..75479ad 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationScrimNestedScrollConnectionTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationScrimNestedScrollConnectionTest.kt
@@ -31,6 +31,7 @@
 @RunWith(AndroidJUnit4::class)
 class NotificationScrimNestedScrollConnectionTest : SysuiTestCase() {
     private var isStarted = false
+    private var wasStarted = false
     private var scrimOffset = 0f
     private var contentHeight = 0f
     private var isCurrentGestureOverscroll = false
@@ -46,7 +47,10 @@
             minVisibleScrimHeight = { MIN_VISIBLE_SCRIM_HEIGHT },
             isCurrentGestureOverscroll = { isCurrentGestureOverscroll },
             onStart = { isStarted = true },
-            onStop = { isStarted = false },
+            onStop = {
+                wasStarted = true
+                isStarted = false
+            },
         )
 
     @Test
@@ -165,6 +169,7 @@
             )
 
         assertThat(offsetConsumed).isEqualTo(Offset.Zero)
+        assertThat(wasStarted).isEqualTo(false)
         assertThat(isStarted).isEqualTo(false)
     }
 
@@ -181,7 +186,9 @@
             )
 
         assertThat(offsetConsumed).isEqualTo(Offset.Zero)
-        assertThat(isStarted).isEqualTo(true)
+        // Returning 0 offset will immediately stop the connection
+        assertThat(wasStarted).isEqualTo(true)
+        assertThat(isStarted).isEqualTo(false)
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index add7ac9..25670cb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -161,7 +161,7 @@
     fun validateMarginStartInSplitShade() =
         testScope.runTest {
             shadeTestUtil.setSplitShade(true)
-            overrideResource(R.dimen.notification_panel_margin_horizontal, 20)
+            overrideDimensionPixelSize(R.dimen.notification_panel_margin_horizontal, 20)
 
             val dimens by collectLastValue(underTest.configurationBasedDimensions)
 
@@ -174,7 +174,7 @@
     fun validateMarginStart() =
         testScope.runTest {
             shadeTestUtil.setSplitShade(false)
-            overrideResource(R.dimen.notification_panel_margin_horizontal, 20)
+            overrideDimensionPixelSize(R.dimen.notification_panel_margin_horizontal, 20)
 
             val dimens by collectLastValue(underTest.configurationBasedDimensions)
 
@@ -189,8 +189,8 @@
             whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight()).thenReturn(5)
             shadeTestUtil.setSplitShade(true)
             overrideResource(R.bool.config_use_large_screen_shade_header, true)
-            overrideResource(R.dimen.large_screen_shade_header_height, 10)
-            overrideResource(R.dimen.keyguard_split_shade_top_margin, 50)
+            overrideDimensionPixelSize(R.dimen.large_screen_shade_header_height, 10)
+            overrideDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin, 50)
 
             val paddingTop by collectLastValue(underTest.paddingTopDimen)
             configurationRepository.onAnyConfigurationChange()
@@ -205,8 +205,8 @@
             whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight()).thenReturn(10)
             shadeTestUtil.setSplitShade(false)
             overrideResource(R.bool.config_use_large_screen_shade_header, true)
-            overrideResource(R.dimen.large_screen_shade_header_height, 10)
-            overrideResource(R.dimen.keyguard_split_shade_top_margin, 50)
+            overrideDimensionPixelSize(R.dimen.large_screen_shade_header_height, 10)
+            overrideDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin, 50)
 
             val paddingTop by collectLastValue(underTest.paddingTopDimen)
 
@@ -221,8 +221,8 @@
             whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight()).thenReturn(10)
             shadeTestUtil.setSplitShade(false)
             overrideResource(R.bool.config_use_large_screen_shade_header, false)
-            overrideResource(R.dimen.large_screen_shade_header_height, 10)
-            overrideResource(R.dimen.keyguard_split_shade_top_margin, 50)
+            overrideDimensionPixelSize(R.dimen.large_screen_shade_header_height, 10)
+            overrideDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin, 50)
 
             val paddingTop by collectLastValue(underTest.paddingTopDimen)
 
@@ -263,8 +263,11 @@
             whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight())
                 .thenReturn(headerHelperHeight)
             overrideResource(R.bool.config_use_large_screen_shade_header, true)
-            overrideResource(R.dimen.large_screen_shade_header_height, headerResourceHeight)
-            overrideResource(R.dimen.notification_panel_margin_top, 0)
+            overrideDimensionPixelSize(
+                R.dimen.large_screen_shade_header_height,
+                headerResourceHeight,
+            )
+            overrideDimensionPixelSize(R.dimen.notification_panel_margin_top, 0)
 
             val dimens by collectLastValue(underTest.configurationBasedDimensions)
 
@@ -282,8 +285,11 @@
             whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight())
                 .thenReturn(headerHelperHeight)
             overrideResource(R.bool.config_use_large_screen_shade_header, true)
-            overrideResource(R.dimen.large_screen_shade_header_height, headerResourceHeight)
-            overrideResource(R.dimen.notification_panel_margin_top, 0)
+            overrideDimensionPixelSize(
+                R.dimen.large_screen_shade_header_height,
+                headerResourceHeight,
+            )
+            overrideDimensionPixelSize(R.dimen.notification_panel_margin_top, 0)
 
             val dimens by collectLastValue(underTest.configurationBasedDimensions)
 
@@ -480,8 +486,8 @@
     fun validateMarginTop() =
         testScope.runTest {
             overrideResource(R.bool.config_use_large_screen_shade_header, false)
-            overrideResource(R.dimen.large_screen_shade_header_height, 50)
-            overrideResource(R.dimen.notification_panel_margin_top, 0)
+            overrideDimensionPixelSize(R.dimen.large_screen_shade_header_height, 50)
+            overrideDimensionPixelSize(R.dimen.notification_panel_margin_top, 0)
 
             val dimens by collectLastValue(underTest.configurationBasedDimensions)
 
@@ -676,8 +682,8 @@
             whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight()).thenReturn(5)
             shadeTestUtil.setSplitShade(true)
             overrideResource(R.bool.config_use_large_screen_shade_header, true)
-            overrideResource(R.dimen.large_screen_shade_header_height, 10)
-            overrideResource(R.dimen.keyguard_split_shade_top_margin, 50)
+            overrideDimensionPixelSize(R.dimen.large_screen_shade_header_height, 10)
+            overrideDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin, 50)
 
             configurationRepository.onAnyConfigurationChange()
             runCurrent()
@@ -1310,4 +1316,9 @@
         communalSceneRepository.setTransitionState(transitionState)
         runCurrent()
     }
+
+    private fun overrideDimensionPixelSize(id: Int, pixelSize: Int) {
+        overrideResource(id, pixelSize)
+        configurationRepository.setDimensionPixelSize(id, pixelSize)
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index 68e17c1..157f818 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
@@ -63,6 +63,7 @@
 import com.android.systemui.shade.ShadeViewStateProvider;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.phone.ui.StatusBarIconController;
 import com.android.systemui.statusbar.phone.ui.TintedIconManager;
@@ -119,6 +120,8 @@
     @Mock
     private StatusBarContentInsetsProvider mStatusBarContentInsetsProvider;
     @Mock
+    private StatusBarContentInsetsProviderStore mStatusBarContentInsetsProviderStore;
+    @Mock
     private UserManager mUserManager;
     @Mock
     private StatusBarUserChipViewModel mStatusBarUserChipViewModel;
@@ -143,7 +146,8 @@
         mShadeViewStateProvider = new TestShadeViewStateProvider();
 
         MockitoAnnotations.initMocks(this);
-
+        when(mStatusBarContentInsetsProviderStore.getDefaultDisplay())
+                .thenReturn(mStatusBarContentInsetsProvider);
         when(mIconManagerFactory.create(any(), any())).thenReturn(mIconManager);
 
         allowTestableLooperAsMainThread();
@@ -175,7 +179,7 @@
                 mKosmos.getKeyguardStatusBarViewModel(),
                 mBiometricUnlockController,
                 mStatusBarStateController,
-                mStatusBarContentInsetsProvider,
+                mStatusBarContentInsetsProviderStore,
                 mUserManager,
                 mStatusBarUserChipViewModel,
                 mSecureSettings,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt
index ba5fb7f..a862fdf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt
@@ -36,14 +36,15 @@
 import com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE
 import com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN
 import com.android.systemui.util.leak.RotationUtils.Rotation
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import junit.framework.Assert.assertTrue
+import com.google.common.truth.Truth.assertWithMessage
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
@@ -1018,7 +1019,39 @@
 
     // Regression test for b/245799099
     @Test
-    fun onMaxBoundsChanged_listenerNotified() {
+    fun onMaxBoundsChanged_afterStart_listenerNotified() {
+        // Start out with an existing configuration with bounds
+        configuration.windowConfiguration.setMaxBounds(0, 0, 100, 100)
+        configurationController.onConfigurationChanged(configuration)
+        val provider =
+            StatusBarContentInsetsProviderImpl(
+                contextMock,
+                configurationController,
+                mock<DumpManager>(),
+                mock<CommandRegistry>(),
+                mock<SysUICutoutProvider>(),
+            )
+        val listener =
+            object : StatusBarContentInsetsChangedListener {
+                var triggered = false
+
+                override fun onStatusBarContentInsetsChanged() {
+                    triggered = true
+                }
+            }
+        provider.start()
+        provider.addCallback(listener)
+
+        // WHEN the config is updated with new bounds
+        configuration.windowConfiguration.setMaxBounds(0, 0, 456, 789)
+        configurationController.onConfigurationChanged(configuration)
+
+        // THEN the listener is notified
+        assertThat(listener.triggered).isTrue()
+    }
+
+    @Test
+    fun onMaxBoundsChanged_beforeStart_listenerNotNotified() {
         // Start out with an existing configuration with bounds
         configuration.windowConfiguration.setMaxBounds(0, 0, 100, 100)
         configurationController.onConfigurationChanged(configuration)
@@ -1041,15 +1074,16 @@
         provider.addCallback(listener)
 
         // WHEN the config is updated with new bounds
+        // but provider is not started
         configuration.windowConfiguration.setMaxBounds(0, 0, 456, 789)
         configurationController.onConfigurationChanged(configuration)
 
-        // THEN the listener is notified
-        assertThat(listener.triggered).isTrue()
+        // THEN the listener is not notified
+        assertThat(listener.triggered).isFalse()
     }
 
     @Test
-    fun onDensityOrFontScaleChanged_listenerNotified() {
+    fun onDensityOrFontScaleChanged_beforeStart_listenerNotNotified() {
         configuration.densityDpi = 12
         val provider =
             StatusBarContentInsetsProviderImpl(
@@ -1069,6 +1103,36 @@
             }
         provider.addCallback(listener)
 
+        // WHEN the config is updated, but the provider is not started
+        configuration.densityDpi = 20
+        configurationController.onConfigurationChanged(configuration)
+
+        // THEN the listener is NOT notified
+        assertThat(listener.triggered).isFalse()
+    }
+
+    @Test
+    fun onDensityOrFontScaleChanged_afterStart_listenerNotified() {
+        configuration.densityDpi = 12
+        val provider =
+            StatusBarContentInsetsProviderImpl(
+                contextMock,
+                configurationController,
+                mock<DumpManager>(),
+                mock<CommandRegistry>(),
+                mock<SysUICutoutProvider>(),
+            )
+        val listener =
+            object : StatusBarContentInsetsChangedListener {
+                var triggered = false
+
+                override fun onStatusBarContentInsetsChanged() {
+                    triggered = true
+                }
+            }
+        provider.start()
+        provider.addCallback(listener)
+
         // WHEN the config is updated
         configuration.densityDpi = 20
         configurationController.onConfigurationChanged(configuration)
@@ -1078,7 +1142,34 @@
     }
 
     @Test
-    fun onThemeChanged_listenerNotified() {
+    fun onThemeChanged_afterStart_listenerNotified() {
+        val provider =
+            StatusBarContentInsetsProviderImpl(
+                contextMock,
+                configurationController,
+                mock<DumpManager>(),
+                mock<CommandRegistry>(),
+                mock<SysUICutoutProvider>(),
+            )
+        val listener =
+            object : StatusBarContentInsetsChangedListener {
+                var triggered = false
+
+                override fun onStatusBarContentInsetsChanged() {
+                    triggered = true
+                }
+            }
+        provider.start()
+        provider.addCallback(listener)
+
+        configurationController.notifyThemeChanged()
+
+        // THEN the listener is notified
+        assertThat(listener.triggered).isTrue()
+    }
+
+    @Test
+    fun onThemeChanged_beforeStart_listenerNotNotified() {
         val provider =
             StatusBarContentInsetsProviderImpl(
                 contextMock,
@@ -1099,8 +1190,7 @@
 
         configurationController.notifyThemeChanged()
 
-        // THEN the listener is notified
-        assertThat(listener.triggered).isTrue()
+        assertThat(listener.triggered).isFalse()
     }
 
     private fun assertRects(
@@ -1109,12 +1199,13 @@
         @Rotation currentRotation: Int,
         @Rotation targetRotation: Int,
     ) {
-        assertTrue(
-            "Rects must match. currentRotation=${RotationUtils.toString(currentRotation)}" +
-                " targetRotation=${RotationUtils.toString(targetRotation)}" +
-                " expected=$expected actual=$actual",
-            expected.equals(actual),
-        )
+        assertWithMessage(
+                "Rects must match. currentRotation=${RotationUtils.toString(currentRotation)}" +
+                    " targetRotation=${RotationUtils.toString(targetRotation)}" +
+                    " expected=$expected actual=$actual"
+            )
+            .that(actual)
+            .isEqualTo(expected)
     }
 
     private fun setNoCutout() {
@@ -1136,8 +1227,7 @@
     }
 
     private fun setCameraProtectionBounds(protectionBounds: Rect) {
-        val protectionInfo =
-            mock<CameraProtectionInfo> { whenever(this.bounds).thenReturn(protectionBounds) }
+        val protectionInfo = mock<CameraProtectionInfo> { on { bounds } doReturn protectionBounds }
         whenever(sysUICutout.cameraProtection).thenReturn(protectionInfo)
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 94753f7..21a317a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -34,6 +34,7 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -56,6 +57,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
@@ -675,8 +677,8 @@
         backCallback.onBackProgressed(event);
         verify(mBouncerViewDelegateBackCallback).onBackProgressed(eq(event));
 
-        backCallback.onBackInvoked();
-        verify(mBouncerViewDelegateBackCallback).onBackInvoked();
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(backCallback::onBackInvoked);
+        verify(mBouncerViewDelegateBackCallback, timeout(1000)).onBackInvoked();
 
         backCallback.onBackCancelled();
         verify(mBouncerViewDelegateBackCallback).onBackCancelled();
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt
index 29e9ba7..d9d8169 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt
@@ -20,6 +20,8 @@
 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.GestureDirection.LEFT
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection.RIGHT
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.Finished
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NotStarted
@@ -61,23 +63,46 @@
     }
 
     @Test
-    fun triggersProgressRelativeToDistance() {
-        assertProgressWhileMovingFingers(deltaX = -SWIPE_DISTANCE / 2, expectedProgress = 0.5f)
-        assertProgressWhileMovingFingers(deltaX = SWIPE_DISTANCE / 2, expectedProgress = 0.5f)
-        assertProgressWhileMovingFingers(deltaX = -SWIPE_DISTANCE, expectedProgress = 1f)
-        assertProgressWhileMovingFingers(deltaX = SWIPE_DISTANCE, expectedProgress = 1f)
+    fun triggersProgressRelativeToDistanceWhenSwipingLeft() {
+        assertProgressWhileMovingFingers(
+            deltaX = -SWIPE_DISTANCE / 2,
+            expected = InProgress(progress = 0.5f, direction = LEFT),
+        )
+        assertProgressWhileMovingFingers(
+            deltaX = -SWIPE_DISTANCE,
+            expected = InProgress(progress = 1f, direction = LEFT),
+        )
     }
 
-    private fun assertProgressWhileMovingFingers(deltaX: Float, expectedProgress: Float) {
+    @Test
+    fun triggersProgressRelativeToDistanceWhenSwipingRight() {
+        assertProgressWhileMovingFingers(
+            deltaX = SWIPE_DISTANCE / 2,
+            expected = InProgress(progress = 0.5f, direction = RIGHT),
+        )
+        assertProgressWhileMovingFingers(
+            deltaX = SWIPE_DISTANCE,
+            expected = InProgress(progress = 1f, direction = RIGHT),
+        )
+    }
+
+    private fun assertProgressWhileMovingFingers(deltaX: Float, expected: InProgress) {
         assertStateAfterEvents(
             events = ThreeFingerGesture.eventsForGestureInProgress { move(deltaX = deltaX) },
-            expectedState = InProgress(progress = expectedProgress),
+            expectedState = expected,
         )
     }
 
     @Test
     fun triggeredProgressIsNoBiggerThanOne() {
-        assertProgressWhileMovingFingers(deltaX = SWIPE_DISTANCE * 2, expectedProgress = 1f)
+        assertProgressWhileMovingFingers(
+            deltaX = SWIPE_DISTANCE * 2,
+            expected = InProgress(progress = 1f, direction = RIGHT),
+        )
+        assertProgressWhileMovingFingers(
+            deltaX = -SWIPE_DISTANCE * 2,
+            expected = InProgress(progress = 1f, direction = LEFT),
+        )
     }
 
     @Test
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index 917e131..5aff124 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -62,9 +62,9 @@
     <string name="kg_bio_try_again_or_pin" msgid="4752168242723808390">"دوباره امتحان کنید یا پین را وارد کنید"</string>
     <string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"دوباره امتحان کنید یا گذرواژه را وارد کنید"</string>
     <string name="kg_bio_try_again_or_pattern" msgid="4867893307468801501">"دوباره امتحان کنید یا الگو را رسم کنید"</string>
-    <string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"بعداز دفعات زیادی تلاش ناموفق، پین لازم است"</string>
-    <string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"بعداز دفعات زیادی تلاش ناموفق، گذرواژه لازم است"</string>
-    <string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"بعداز دفعات زیادی تلاش ناموفق، الگو لازم است"</string>
+    <string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"پس‌از تلاش‌های بسیار زیاد ناموفق، پین لازم است"</string>
+    <string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"پس‌از تلاش‌های بسیار زیاد ناموفق، گذرواژه لازم است"</string>
+    <string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"پس‌از تلاش‌های بسیار زیاد ناموفق، الگو لازم است"</string>
     <string name="kg_unlock_with_pin_or_fp" msgid="5635161174698729890">"قفل‌گشایی با پین یا اثر انگشت"</string>
     <string name="kg_unlock_with_password_or_fp" msgid="2251295907826814237">"قفل‌گشایی با گذرواژه یا اثر انگشت"</string>
     <string name="kg_unlock_with_pattern_or_fp" msgid="2391870539909135046">"قفل‌گشایی با الگو یا اثر انگشت"</string>
@@ -77,12 +77,12 @@
     <string name="kg_prompt_password_auth_timeout" msgid="5809110458491920871">"امنیت بیشتر لازم است. گذرواژه مدتی استفاده نشده است."</string>
     <string name="kg_prompt_pattern_auth_timeout" msgid="1860605401869262178">"امنیت بیشتر لازم است. مدتی از الگو استفاده نشده است."</string>
     <string name="kg_prompt_auth_timeout" msgid="6620679830980315048">"امنیت بیشتر لازم است. قفل دستگاه مدتی باز نشده است."</string>
-    <string name="kg_face_locked_out" msgid="2751559491287575">"قفل‌گشایی با چهره ممکن نیست. دفعات زیادی تلاش ناموفق"</string>
-    <string name="kg_fp_locked_out" msgid="6228277682396768830">"قفل با اثرانگشت باز نمی‌شود. دفعات زیادی تلاش ناموفق"</string>
+    <string name="kg_face_locked_out" msgid="2751559491287575">"قفل‌گشایی با چهره ممکن نیست. تلاش‌های بسیار زیاد ناموفق."</string>
+    <string name="kg_fp_locked_out" msgid="6228277682396768830">"قفل با اثرانگشت باز نمی‌شود. تلاش‌های بسیار زیاد ناموفق."</string>
     <string name="kg_trust_agent_disabled" msgid="5400691179958727891">"عامل معتبر دردسترس نیست"</string>
     <string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"تلاش‌های بسیار زیادی با پین اشتباه انجام شده است"</string>
-    <string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"تلاش‌های بسیار زیادی با الگوی اشتباه انجام شده است"</string>
-    <string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"تلاش‌های بسیار زیادی با گذرواژه اشتباه انجام شده است"</string>
+    <string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"تلاش‌های بسیار زیاد با الگوی اشتباه"</string>
+    <string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"تلاش‌های بسیار زیاد با گذرواژه اشتباه"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{# ثانیه دیگر دوباره امتحان کنید.}one{# ثانیه دیگر دوباره امتحان کنید.}other{# ثانیه دیگر دوباره امتحان کنید.}}"</string>
     <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"پین سیم‌کارت را وارد کنید."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"پین سیم‌کارت «<xliff:g id="CARRIER">%1$s</xliff:g>» را وارد کنید."</string>
diff --git a/packages/SystemUI/res/layout/contextual_edu_dialog.xml b/packages/SystemUI/res/layout/contextual_edu_dialog.xml
index ee42b23..7eb6efe 100644
--- a/packages/SystemUI/res/layout/contextual_edu_dialog.xml
+++ b/packages/SystemUI/res/layout/contextual_edu_dialog.xml
@@ -40,6 +40,5 @@
         android:fontFamily="google-sans-medium"
         android:maxWidth="280dp"
         android:textColor="?androidprv:attr/materialColorOnTertiaryFixed"
-        android:textSize="14sp"
-        android:textStyle="bold" />
+        android:textSize="14sp" />
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
index 0029180..2b40df4 100644
--- a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
+++ b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
@@ -148,7 +148,7 @@
                         android:orientation="vertical"
                         android:clickable="false"
                         android:layout_width="wrap_content"
-                        android:layout_height="match_parent"
+                        android:layout_height="wrap_content"
                         android:gravity="start|center_vertical">
                         <TextView
                             android:id="@+id/mobile_title"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index f00ba9d..3f68258 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Vou ikoon uit"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"of"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Sleephandvatsel"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeer met jou sleutelbord"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Leer kortpadsleutels"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeer met jou raakpaneel"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Verskaf deur apps"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Vertoon"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Onbekend"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 9f759fb..c66d7a6 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"መዘርጊያ አዶ"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ወይም"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"መያዣ ይጎትቱ"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"የቁልፍ ሰሌዳዎን በመጠቀም ያስሱ"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"የቁልፍ ሰሌዳ አቋራጮችን ይወቁ"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"የመዳሰሻ ሰሌዳዎን በመጠቀም ያስሱ"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"በመተግበሪያዎች የቀረበ"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ማሳያ"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ያልታወቀ"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c2539a7..c559488 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"رمز التوسيع"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"أو"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"مقبض السحب"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"التنقّل باستخدام لوحة المفاتيح"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"تعرَّف على اختصارات لوحة المفاتيح"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"التنقّل باستخدام لوحة اللمس"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"مقدَّمة من التطبيقات"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"العرض"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"غير معروفة"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 240d29e..c006caa 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"বিস্তাৰ কৰাৰ চিহ্ন"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"অথবা"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ড্ৰেগ হেণ্ডেল"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"কীব’ৰ্ড ব্যৱহাৰ কৰি নেভিগে’ট কৰক"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"কীব’ৰ্ডৰ শ্বৰ্টকাটসমূহৰ বিষয়ে জানক"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"আপোনাৰ টাচ্চপেড ব্যৱহাৰ কৰি নেভিগে’ট কৰক"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"এপে প্ৰদান কৰা"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ডিছপ্লে’"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"অজ্ঞাত"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index d3ebd7d..f33fa77 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"İkonanı genişləndirin"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"və ya"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Dəstəyi çəkin"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klaviaturadan istifadə edərək hərəkət edin"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Klaviatura qısayolları haqqında öyrənin"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Taçpeddən istifadə edərək hərəkət edin"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Tətbiqlər tərəfindən təmin edilir"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Displey"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Naməlum"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index a1fc846..11db758 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -555,7 +555,7 @@
     <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Prebaci ceo ekran"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Kada prebacujete ceo ekran, vidi se sve što je na njemu. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, audio i video sadržaj."</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Kada prebacujete aplikaciju, vidi 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="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Prebacivanje ekrana"</string>
+    <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Prebacii ekran"</string>
     <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Odaberite aplikaciju koju želite da prebacite"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Želite da počnete da delite?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Kada delite, snimate ili prebacujete, Android ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, i audio i video sadržaj."</string>
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za proširivanje"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Marker za prevlačenje"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tastature"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o tasterskim prečicama"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću tačpeda"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Obezbeđuju aplikacije"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ekran"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 526a11e..8ba951f 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок \"Разгарнуць\""</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"або"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер перацягвання"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навігацыя з дапамогай клавіятуры"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Азнаёмцеся са спалучэннямі клавіш"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навігацыя з дапамогай сэнсарнай панэлі"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Забяспечваюцца праграмамі"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Экран"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Невядома"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index b843068..71649cf 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за разгъване"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Манипулатор за преместване с плъзгане"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навигирайте посредством клавиатурата си"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Научете за клавишните комбинации"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навигирайте посредством сензорния панел"</string>
@@ -1462,4 +1464,6 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Предоставено от приложения"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Екран"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Неизвестно"</string>
+    <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Нулиране на панелите"</string>
+    <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Да се възстанови ли първоначалният ред и размери на панелите?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 0732387..92056c9 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"আইকন বড় করুন"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"অথবা"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"টেনে আনার হ্যান্ডেল"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"আপনার কীবোর্ড ব্যবহার করে নেভিগেট করুন"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"কীবোর্ড শর্টকাট সম্পর্কে জানুন"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"আপনার টাচপ্যাড ব্যবহার করে নেভিগেট করুন"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"অ্যাপের তরফ থেকে দেওয়া"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ডিসপ্লে"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"অজানা"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index b1146f4..a02b604 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona proširivanja"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ručica za prevlačenje"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tastature"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o prečicama tastature"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću dodirne podloge"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Pružaju aplikacije"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Prikaz"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index a836b97..7ea0236 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -129,8 +129,8 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Comparteix"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"S\'ha desat la gravació de pantalla"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Toca per veure-la"</string>
-    <string name="screenrecord_save_error" msgid="5862648532560118815">"S\'ha produït un error en desar la gravació de la pantalla"</string>
-    <string name="screenrecord_start_error" msgid="2200660692479682368">"S\'ha produït un error en iniciar la gravació de pantalla"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Hi ha hagut un error en desar la gravació de la pantalla"</string>
+    <string name="screenrecord_start_error" msgid="2200660692479682368">"Hi ha hagut un error en iniciar la gravació de pantalla"</string>
     <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"Vols aturar la gravació?"</string>
     <string name="screenrecord_stop_dialog_message" msgid="6262768207331626817">"Ara mateix estàs gravant tota la pantalla"</string>
     <string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Ara mateix estàs gravant <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -159,8 +159,8 @@
     <string name="issuerecord_share_label" msgid="3992657993619876199">"Comparteix"</string>
     <string name="issuerecord_save_title" msgid="4161043023696751591">"S\'ha desat la gravació del problema"</string>
     <string name="issuerecord_save_text" msgid="1205985304551521495">"Toca per veure"</string>
-    <string name="issuerecord_save_error" msgid="6913040083446722726">"S\'ha produït un error en desar la gravació del problema"</string>
-    <string name="issuerecord_start_error" msgid="3402782952722871190">"S\'ha produït un error en iniciar la gravació del problema"</string>
+    <string name="issuerecord_save_error" msgid="6913040083446722726">"Hi ha hagut un error en desar la gravació del problema"</string>
+    <string name="issuerecord_start_error" msgid="3402782952722871190">"Hi ha hagut un error en iniciar la gravació del problema"</string>
     <string name="immersive_cling_title" msgid="8372056499315585941">"Visualització en pantalla completa"</string>
     <string name="immersive_cling_description" msgid="2717426731830851921">"Per sortir, llisca cap avall des de la part superior de la pantalla"</string>
     <string name="immersive_cling_positive" msgid="3076681691468978568">"Entesos"</string>
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Desplega la icona"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ansa per arrossegar"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega amb el teclat"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprèn les tecles de drecera"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega amb el ratolí tàctil"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Proporcionat per aplicacions"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Pantalla"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconegut"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 70bdb62..750e75d 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozbalení"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"nebo"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Úchyt pro přetažení"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigujte pomocí klávesnice"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Naučte se klávesové zkratky"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigujte pomocí touchpadu"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Poskytováno aplikacemi"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Displej"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznámé"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index eeece4c..b52b182 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikon for Udvid"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Håndtag"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviger ved hjælp af dit tastatur"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Se tastaturgenveje"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviger ved hjælp af din touchplade"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Fra apps"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Skærm"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ukendt"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 9570314..ba6452f 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Symbol „Maximieren“"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"oder"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ziehpunkt"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigation mit der Tastatur"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Informationen zu Tastenkombinationen"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigation mit dem Touchpad"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Von Apps bereitgestellt"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unbekannt"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 5551740..4cccb5a 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Εικονίδιο ανάπτυξης"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ή"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Λαβή μεταφοράς"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Πλοήγηση με το πληκτρολόγιο"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Μάθετε συντομεύσεις πληκτρολογίου"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Πλοήγηση με την επιφάνεια αφής"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Παρέχεται από εφαρμογές"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Προβολή"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Άγνωστο"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index df9d210..e96dd8c 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Provided by apps"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 28cb9a3..eee14f8 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -1405,6 +1405,7 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
+    <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Keyboard Settings"</string>
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string>
@@ -1462,4 +1463,6 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Provided by apps"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
+    <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Reset tiles"</string>
+    <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Reset tiles to their original order and sizes?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index df9d210..e96dd8c 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Provided by apps"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index df9d210..e96dd8c 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Provided by apps"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index e39b2a4..97bd547 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -554,7 +554,7 @@
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir una app"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Transmitir pantalla entera"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Cuando transmitas la pantalla entera, todo lo que se muestre es visible. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Cuando transmitas una app, todo lo que se muestre o reproduzcas en ella será visible. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Cuando transmitas una app, todo lo que se muestre o reproduzca en ella será visible. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Transmitir pantalla"</string>
     <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Elige la app para transmitir"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"¿Quieres empezar a compartir?"</string>
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícono de expandir"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega con el teclado"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende combinaciones de teclas"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega con el panel táctil"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Proporcionado por apps"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Pantalla"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconocido"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 6d77be4..8d018bb 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icono de desplegar"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Desplázate con el teclado"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende combinaciones de teclas"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Desplázate con el panel táctil"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Proporcionado por aplicaciones"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Pantalla"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconocido"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index ed14409..53651da 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -556,7 +556,7 @@
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Kogu ekraanikuva ülekandmisel on kogu sellel kuvatav sisu nähtav. Seega olge ettevaatlik näiteks paroolide, makseteabe, sõnumite, fotode ning heli ja videoga."</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Rakenduse ülekandmisel on kogu rakenduses kuvatav või esitatav sisu nähtav. Seega olge ettevaatlik näiteks paroolide, makseteabe, sõnumite, fotode ning heli ja videoga."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Kanna üle ekraanikuva"</string>
-    <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Vali ülekandmiseks rakendus"</string>
+    <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Valige ülekandmiseks rakendus"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Kas alustada jagamist?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Kui jagate, salvestate või kannate üle, on Androidil juurdepääs kõigele, mis on teie ekraanikuval nähtaval või mida teie seadmes esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Kui jagate, salvestate või kannate rakendust üle, on Androidil juurdepääs kõigele, mida selles rakenduses kuvatakse või esitatakse. Seega olge paroolide, makseteabe, sõnumite, fotode, heli ja videoga ettevaatlik."</string>
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Laiendamisikoon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"või"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Lohistamispide"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeerige klaviatuuri abil"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Õppige klaviatuuri otseteid"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeerige puuteplaadi abil"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Rakendustelt"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Kuva"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Teadmata"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 2fb75d3..f739862 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Zabaltzeko ikonoa"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"edo"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Arrastatzeko kontrol-puntua"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Nabigatu teklatua erabilita"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ikasi lasterbideak"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Nabigatu ukipen-panela erabilita"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Aplikazioenak"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Pantaila"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ezezagunak"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b18c84a..3d0b720 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"نماد ازهم بازکردن"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"یا"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"دستگیره کشاندن"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"پیمایش کردن بااستفاده از صفحه‌کلید"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"آشنایی با میان‌برهای صفحه‌کلید"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"پیمایش کردن بااستفاده از صفحه لمسی"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ارائه‌شده از برنامه‌ها"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"نمایشگر"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"نامشخص"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 4602741..ca6a97b 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Laajennuskuvake"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"tai"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vetokahva"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Siirry käyttämällä näppäimistöä"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Opettele pikanäppäimiä"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Siirry käyttämällä kosketuslevyä"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Sovellusten tarjoama"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Näyttö"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tuntematon"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 77434a5..4496b5e 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icône Développer"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Poignée de déplacement"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviguer à l\'aide de votre clavier"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Apprenez à utiliser les raccourcis-clavier"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviguer à l\'aide de votre pavé tactile"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Fournies par des applis"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Affichage"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Inconnu"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index fa16862..77b98eb 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icône Développer"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Poignée de déplacement"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviguer à l\'aide du clavier"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Découvrir les raccourcis clavier"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviguer à l\'aide de votre pavé tactile"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Fournis par des applis"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Écran"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Inconnu"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 1d2c785..3b94095 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icona de despregar"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega co teclado"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende a usar os atallos de teclado"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega co panel táctil"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Provenientes de aplicacións"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Visualización"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Categoría descoñecida"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index c6014b1..f87184a 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"\'મોટું કરો\'નું આઇકન"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"અથવા"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ઑબ્જેક્ટ ખેંચવાનું હૅન્ડલ"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"તમારા કીબોર્ડ વડે નૅવિગેટ કરો"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"કીબોર્ડ શૉર્ટકર્ટ જાણો"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"તમારા ટચપૅડ વડે નૅવિગેટ કરો"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ઍપ દ્વારા પ્રદાન કરવામાં આવેલી"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ડિસ્પ્લે"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"અજાણ"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 28a4f2b..767f9df 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"बड़ा करने का आइकॉन"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"या"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"खींचकर छोड़ने वाला हैंडल"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"कीबोर्ड का इस्तेमाल करके नेविगेट करें"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"कीबोर्ड शॉर्टकट के बारे में जानें"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"टचपैड का इस्तेमाल करके नेविगेट करें"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ऐप्लिकेशन से मिली जानकारी"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"डिसप्ले"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"कोई जानकारी नहीं है"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index cc19bea..f040451 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za proširivanje"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Marker za povlačenje"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tipkovnice"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o tipkovnim prečacima"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću dodirne podloge"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Pružaju aplikacije"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Prikaz"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 9ee748b..629e2ff 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kibontás ikon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"vagy"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Fogópont"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigáció a billentyűzet segítségével"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Billentyűparancsok megismerése"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigálás az érintőpaddal"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Alkalmazás által biztosított"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Kijelző"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ismeretlen"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index b07a785..92da53b 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -312,7 +312,7 @@
     <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Փոխանցել աուդիոն"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Աուդիոյի փոխանցում"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button_accessibility" msgid="7604615019302091708">"անցնել աուդիոյի փոխանցման կարգավորումներ"</string>
-    <string name="quick_settings_bluetooth_audio_sharing_dialog_message" msgid="4251807313264307426">"Այս սարքի երաժշտությունն ու տեսանյութերը երկու ականջակալներում էլ կնվագարկվեն"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_dialog_message" msgid="4251807313264307426">"Այս սարքի երաժշտությունն ու տեսանյութերը երկուսի ականջակալներում էլ կնվագարկվեն"</string>
     <string name="quick_settings_bluetooth_audio_sharing_dialog_title" msgid="4406818346036286793">"Կիսվեք ձեր աուդիոյով"</string>
     <string name="quick_settings_bluetooth_audio_sharing_dialog_subtitle" msgid="3014906864710059236">"<xliff:g id="AVAILABLE_DEVICE_NAME">%1$s</xliff:g> և <xliff:g id="ACTIVE_DEVICE_NAME">%2$s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_audio_sharing_dialog_switch_to_button" msgid="7546825655978203773">"Անցնել <xliff:g id="AVAILABLE_DEVICE_NAME">%1$s</xliff:g> սարքին"</string>
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ծավալել պատկերակը"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"կամ"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Տեղափոխման նշիչ"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Կողմնորոշվեք ձեր ստեղնաշարի օգնությամբ"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Սովորեք օգտագործել ստեղնային դյուրանցումները"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Կողմնորոշվեք ձեր հպահարթակի օգնությամբ"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Տրամադրվել են հավելվածների կողմից"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Էկրան"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Անհայտ"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 84a45c6..d054405 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikon luaskan"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handel geser"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Menavigasi menggunakan keyboard"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Pelajari pintasan keyboard"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Menavigasi menggunakan touchpad"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Disediakan oleh aplikasi"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Tampilan"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tidak diketahui"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index f27790c..607f48f 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Stækka tákn"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eða"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Dragkló"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Flettu með því að nota lyklaborðið"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Kynntu þér flýtilykla"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Flettu með því að nota snertiflötinn"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Frá forritum"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Skjár"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Óþekkt"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 7ace302..0cbdb86 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icona Espandi"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"oppure"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Punto di trascinamento"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviga usando la tastiera"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Informazioni sulle scorciatoie da tastiera"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviga usando il touchpad"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Forniti dalle app"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Sconosciuti"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index b5783cf..465d8f5 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"סמל ההרחבה"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"או"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"נקודת האחיזה לגרירה"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ניווט באמצעות המקלדת"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"מידע על מקשי קיצור"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ניווט באמצעות לוח המגע"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"מסופקים על ידי אפליקציות"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"מסך"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"לא ידוע"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 8427f67..6df9f73 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"開くアイコン"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"または"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ドラッグ ハンドル"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"キーボードを使用して移動する"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"キーボード ショートカットの詳細"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"タッチパッドを使用して移動する"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"アプリから提供"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ディスプレイ"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"不明"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 3b0732d..b30c748 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ხატულის გაფართოება"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ან"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"სახელური ჩავლებისთვის"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ნავიგაცია კლავიატურის გამოყენებით"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"კლავიატურის მალსახმობების სწავლა"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ნავიგაცია სენსორული პანელის გამოყენებით"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"მოწოდებულია აპების მიერ"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ეკრანი"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"უცნობი"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 6511558..c9517ec 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жаю белгішесі"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"немесе"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Сүйрейтін тетік"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Пернетақтамен жұмыс істеңіз"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Перне тіркесімдерін үйреніңіз."</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Сенсорлық тақтамен жұмыс істеңіз"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Қолданбалар ұсынған"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Дисплей"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Белгісіз"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 7b7f912..10a125b 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"រូបតំណាង \"ពង្រីក\""</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ឬ"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ដង​អូស"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"រុករកដោយប្រើក្ដារចុចរបស់អ្នក"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ស្វែងយល់អំពីផ្លូវកាត់​ក្ដារ​ចុច"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"រុករកដោយប្រើផ្ទាំងប៉ះរបស់អ្នក"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ផ្ដល់ជូនដោយកម្មវិធី"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ផ្ទាំងបង្ហាញ"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"មិនស្គាល់"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index c4417b7..3ff0629 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ವಿಸ್ತೃತಗೊಳಿಸುವ ಐಕಾನ್"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ಅಥವಾ"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ಡ್ರ್ಯಾಗ್‌ ಹ್ಯಾಂಡಲ್‌"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ ಬಳಸಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಕಲಿಯಿರಿ"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್ ಬಳಸಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ಆ್ಯಪ್‌ಗಳಿಂದ ಒದಗಿಸಲಾಗಿದೆ"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ಡಿಸ್‌ಪ್ಲೇ"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ಅಪರಿಚಿತ"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 5602ee7..0c1dc01e 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"확장 아이콘"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"또는"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"드래그 핸들"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"키보드를 사용하여 이동"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"단축키 알아보기"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"터치패드를 사용하여 이동"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"앱에서 제공"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"디스플레이"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"알 수 없음"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 93777db..b74e494 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жайып көрсөтүү сүрөтчөсү"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"же"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Cүйрөө маркери"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Нерселерге баскычтоп аркылуу өтүңүз"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ыкчам баскычтар тууралуу билип алыңыз"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Нерселерге сенсордук такта аркылуу өтүңүз"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Колдонмолор сунуштады"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Экран"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Белгисиз"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 07f3853..ce8c959 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ໄອຄອນຂະຫຍາຍ"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ຫຼື"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ບ່ອນຈັບລາກ"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ນຳທາງໂດຍໃຊ້ແປ້ນພິມຂອງທ່ານ"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ສຶກສາຄີລັດ"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ນຳທາງໂດຍໃຊ້ແຜ່ນສຳຜັດຂອງທ່ານ"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ສະໜອງໃຫ້ໂດຍແອັບ"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ການສະແດງຜົນ"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ບໍ່ຮູ້ຈັກ"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 605b8dd..a7906b6 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Išskleidimo piktograma"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"arba"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vilkimo rankenėlė"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naršykite naudodamiesi klaviatūra"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Sužinokite apie sparčiuosius klavišus"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naršykite naudodamiesi jutikline dalimi"</string>
@@ -1462,4 +1464,6 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Teikia programos"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ekranas"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nežinoma"</string>
+    <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Išklotinės nustatymas iš naujo"</string>
+    <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Iš naujo nustatyti išklotinės pradinę tvarką ir dydžius?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 0393ad5..cff7278 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Izvēršanas ikona"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"vai"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vilkšanas turis"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Pārvietošanās, izmantojot tastatūru"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Uzziniet par īsinājumtaustiņiem."</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Pārvietošanās, izmantojot skārienpaliktni"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Nodrošina lietotnes"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Displejs"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nezināma"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 6b956ec..464ef33 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за проширување"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Рачка за влечење"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Движете се со користење на тастатурата"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Научете кратенки од тастатурата"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Движете се со користење на допирната подлога"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Обезбедено од апликации"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Екран"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Непознато"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index cd0a0442d3..08e9799 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"വികസിപ്പിക്കൽ ഐക്കൺ"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"അല്ലെങ്കിൽ"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"വലിച്ചിടുന്നതിനുള്ള ഹാൻഡിൽ"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"നിങ്ങളുടെ കീബോർഡ് ഉപയോഗിച്ച് നാവിഗേറ്റ് ചെയ്യുക"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"കീബോർഡ് കുറുക്കുവഴികൾ മനസ്സിലാക്കുക"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"നിങ്ങളുടെ ടച്ച്‌പാഡ് ഉപയോഗിച്ച് നാവിഗേറ്റ് ചെയ്യുക"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ആപ്പുകൾ നൽകുന്നത്"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ഡിസ്‌പ്ലേ"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"അജ്ഞാതം"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index e4f1746..73b6aab 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Дэлгэх дүрс тэмдэг"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"эсвэл"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Чирэх бариул"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Гараа ашиглан шилжих"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Товчлуурын шууд холбоосыг мэдэж аваарай"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Мэдрэгч самбараа ашиглан шилжээрэй"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Аппуудаас өгсөн"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Дэлгэц"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Тодорхойгүй"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 458fe2c..22044c2 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"विस्तार करा आयकन"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"किंवा"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ड्रॅग हॅंडल"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"तुमचा कीबोर्ड वापरून नेव्हिगेट करा"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"कीबोर्ड शॉर्टकट जाणून घ्या"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"तुमचा टचपॅड वापरून नेव्हिगेट करा"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"अ‍ॅप्सद्वारे पुरवलेले"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"डिस्प्ले"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"अज्ञात"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 8912366..7ee2dcd 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kembangkan ikon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Pemegang seret"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigasi menggunakan papan kekunci anda"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ketahui pintasan papan kekunci"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigasi menggunakan pad sentuh anda"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Disediakan oleh apl"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Paparan"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tidak diketahui"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index e388001..d3ccaf9 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -555,7 +555,7 @@
     <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"ဖန်သားပြင်တစ်ခုလုံးကို ကာစ်လုပ်ရန်"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"သင့်ဖန်သားပြင်တစ်ခုလုံးကို ကာစ်လုပ်သည့်အခါ ဖန်သားပြင်ပေါ်ရှိ အရာအားလုံးကို မြင်နိုင်သည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"အက်ပ်တစ်ခုကို ကာစ်လုပ်သည့်အခါ ယင်းအက်ပ်တွင် ပြထားသော (သို့) ဖွင့်ထားသော အရာအားလုံးကို မြင်နိုင်သည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
-    <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"စခရင် ကာစ်လုပ်ရန်"</string>
+    <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"ဖန်သားပြင်ကာစ်လုပ်ရန်"</string>
     <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"ကာစ်လုပ်ရန် အက်ပ်ရွေးခြင်း"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"စတင်မျှဝေမလား။"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"မျှဝေ၊ ရုပ်သံဖမ်း (သို့) ကာစ်လုပ်သည့်အခါ Android သည် သင့်ဖန်သားပြင်တွင် မြင်နိုင်သည့် (သို့) သင့်စက်တွင် ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ပိုပြရန် သင်္ကေတ"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"သို့မဟုတ်"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ဖိဆွဲအထိန်း"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"သင့်ကီးဘုတ်ကိုသုံး၍ လမ်းညွှန်ခြင်း"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"လက်ကွက်ဖြတ်လမ်းများကို လေ့လာပါ"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"သင့်တာ့ချ်ပက်ကိုသုံး၍ လမ်းညွှန်ခြင်း"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"အက်ပ်များက ပံ့ပိုးထားသည်"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ဖန်သားပြင်"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"အမျိုးအမည်မသိ"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 49c004b..03e9f35 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Vis-ikon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Håndtak"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviger med tastaturet"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Lær deg hurtigtaster"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviger med styreflaten"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Levert av apper"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Skjerm"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ukjent"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index e364e9e..4d165cc 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"\"एक्स्पान्ड गर्नुहोस्\" आइकन"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"वा"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ड्र्याग ह्यान्डल"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"किबोर्ड प्रयोग गरी नेभिगेट गर्नुहोस्"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"किबोर्डका सर्टकटहरू प्रयोग गर्न सिक्नुहोस्"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"टचप्याड प्रयोग गरी नेभिगेट गर्नुहोस्"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"एपले उपलब्ध गराएका"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"डिस्प्ले"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"अज्ञात"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 0f8eb11..4249cb7 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icoon voor uitvouwen"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"of"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handgreep voor slepen"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeren met je toetsenbord"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Leer sneltoetsen die je kunt gebruiken"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeren met je touchpad"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Geleverd door apps"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Scherm"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Onbekend"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 16127eb..e2cd9ec 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ଆଇକନକୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"କିମ୍ବା"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ଡ୍ରାଗ ହେଣ୍ଡେଲ"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ଆପଣଙ୍କ କୀବୋର୍ଡ ବ୍ୟବହାର କରି ନାଭିଗେଟ କରନ୍ତୁ"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"କୀବୋର୍ଡ ସର୍ଟକଟଗୁଡ଼ିକ ବିଷୟରେ ଜାଣନ୍ତୁ"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ଆପଣଙ୍କ ଟଚପେଡ ବ୍ୟବହାର କରି ନାଭିଗେଟ କରନ୍ତୁ"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ଆପ୍ସ ଦ୍ୱାରା ପ୍ରଦାନ କରାଯାଇଛି"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ଡିସପ୍ଲେ"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ଅଜଣା"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 63de1a6..3c3102c 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ਪ੍ਰਤੀਕ ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ਜਾਂ"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ਘਸੀਟਣ ਵਾਲਾ ਹੈਂਡਲ"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ਆਪਣੇ ਕੀ-ਬੋਰਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ ਬਾਰੇ ਜਾਣੋ"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ਆਪਣੇ ਟੱਚਪੈਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ਐਪਾਂ ਵੱਲੋਂ ਮੁਹੱਈਆ ਕੀਤਾ ਗਿਆ"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ਡਿਸਪਲੇ"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ਅਗਿਆਤ"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index a5dbc06..5b0fa56 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozwijania"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"lub"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Uchwyt do przeciągania"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Nawiguj za pomocą klawiatury"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Dowiedz się więcej o skrótach klawiszowych"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Nawiguj za pomocą touchpada"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Z aplikacji"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Wyświetlacz"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nieznane"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index da192e3..9386027 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Alça de arrastar"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue usando o teclado"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos do teclado"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue usando o touchpad"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Fornecidos por apps"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Exibição"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconhecidos"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 127a97ea..fcd9bba 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -687,7 +687,7 @@
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Áudio espacial"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Desativar"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Corrigido"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head tracking"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Posição da cabeça"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Toque para alterar o modo de campainha"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar som"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"reativar som"</string>
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone de expandir"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Indicador para arrastar"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue com o teclado"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos de teclado"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue com o touchpad"</string>
@@ -1462,4 +1464,6 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Disponibilizado por apps"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ecrã"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconhecido"</string>
+    <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Reponha os mosaicos"</string>
+    <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Repor os mosaicos para a ordem e os tamanhos originais?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index da192e3..9386027 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Alça de arrastar"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue usando o teclado"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos do teclado"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue usando o touchpad"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Fornecidos por apps"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Exibição"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconhecidos"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 5c97ab5..42d24cd 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Pictograma de extindere"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"sau"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ghidaj de tragere"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navighează folosind tastatura"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Învață comenzile rapide de la tastatură"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navighează folosind touchpadul"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Oferite de aplicații"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ecran"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Necunoscută"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 5ae021d..cbb89c0 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок \"Развернуть\""</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер перемещения"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навигация с помощью клавиатуры"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Узнайте о сочетаниях клавиш."</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навигация с помощью сенсорной панели"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Приложения"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Экран"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Неизвестно"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 03c2ba4..1ff4316 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"දිගහැරීම් නිරූපකය"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"හෝ"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ඇදීම් හැඬලය"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ඔබේ යතුරු පුවරුව භාවිතයෙන් සංචාලනය කරන්න"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"යතුරුපුවරු කෙටිමං ඉගෙන ගන්න"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ඔබේ ස්පර්ශ පෑඩ් භාවිතයෙන් සංචාලනය කරන්න"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"යෙදුම් මගින් සපයනු ලැබේ"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"සංදර්ශකය"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"නොදනී"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index ac80ae2..5f5ead1 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozbalenia"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"alebo"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Presúvadlo"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Prechádzajte pomocou klávesnice"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Naučte sa klávesové skratky"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Prechádzajte pomocou touchpadu"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Poskytnuté aplikáciami"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Zobrazovanie"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznáme"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index f953a94..3c027d9 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za razširitev"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ali"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ročica za vlečenje"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krmarjenje s tipkovnico"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Učenje bližnjičnih tipk"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krmarjenje s sledilno ploščico"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Zagotavljajo aplikacije"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Zaslon"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznano"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 0166acc..e6f84f4 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona e zgjerimit"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ose"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Doreza e zvarritjes"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigo duke përdorur tastierën tënde"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Mëso shkurtoret e tastierës"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigo duke përdorur bllokun me prekje"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Mundësuar nga aplikacionet"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ekrani"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nuk njihet"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index d7075ad..e82e2a2 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -555,7 +555,7 @@
     <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Пребаци цео екран"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Када пребацујете цео екран, види се све што је на њему. Зато пазите на лозинке, информације о плаћању, поруке, слике, аудио и видео садржај."</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Када пребацујете апликацију, види се сав садржај који се приказује или пушта у њој. Зато пазите на лозинке, информације о плаћању, поруке, слике, аудио и видео садржај."</string>
-    <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Пребацивање екрана"</string>
+    <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Пребации екран"</string>
     <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Одаберите апликацију коју желите да пребаците"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Желите да почнете да делите?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Када делите, снимате или пребацујете, Android има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Зато пазите на лозинке, информације о плаћању, поруке, слике, и аудио и видео садржај."</string>
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за проширивање"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер за превлачење"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Крећите се помоћу тастатуре"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Сазнајте више о тастерским пречицама"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Крећите се помоћу тачпеда"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Обезбеђују апликације"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Екран"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Непознато"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index e03fc27..06e4607 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikonen Utöka"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handtag"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigera med tangentbordet"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Lär dig kortkommandon"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigera med styrplattan"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Tillhandahålls av appar"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Skärm"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Okänt"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 0ab6f7d..b8a9dc9 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Panua aikoni"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"au"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Aikoni ya buruta"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Kusogeza kwa kutumia kibodi yako"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Jifunze kuhusu mikato ya kibodi"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Kusogeza kwa kutumia padi yako ya kugusa"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Vinavyotolewa na programu"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Maonyesho"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Visivyojulikana"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index f930d84..b53c8ec 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"விரிவாக்குவதற்கான ஐகான்"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"அல்லது"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"இழுப்பதற்கான ஹேண்டில்"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"கீபோர்டைப் பயன்படுத்திச் செல்லுதல்"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"கீபோர்டு ஷார்ட்கட்கள் குறித்துத் தெரிந்துகொள்ளுங்கள்"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"டச்பேடைப் பயன்படுத்திச் செல்லுதல்"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ஆப்ஸ் வழங்குபவை"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"டிஸ்ப்ளே"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"தெரியவில்லை"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 85973df..d185851 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"విస్తరించండి చిహ్నం"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"లేదా"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"లాగే హ్యాండిల్"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"మీ కీబోర్డ్ ఉపయోగించి నావిగేట్ చేయండి"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"కీబోర్డ్ షార్ట్‌కట్‌ల గురించి తెలుసుకోండి"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"మీ టచ్‌ప్యాడ్‌ని ఉపయోగించి నావిగేట్ చేయండి"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"యాప్‌ల ద్వారా అందించబడినవి"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"డిస్‌ప్లే"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"తెలియదు"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 67006b6..a2a68c1 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ไอคอนขยาย"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"หรือ"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"แฮนเดิลการลาก"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ไปยังส่วนต่างๆ โดยใช้แป้นพิมพ์"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ดูข้อมูลเกี่ยวกับแป้นพิมพ์ลัด"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ไปยังส่วนต่างๆ โดยใช้ทัชแพด"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ให้บริการโดยแอป"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"จอแสดงผล"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ไม่ทราบ"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e41c53f..4349043 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"I-expand ang icon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handle sa pag-drag"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Mag-navigate gamit ang iyong keyboard"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Matuto ng mga keyboard shortcut"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Mag-navigate gamit ang iyong touchpad"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Ibinibigay ng mga app"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Hindi Alam"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 1dab64a..cf892e0 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Genişlet simgesi"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"veya"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Sürükleme tutamacı"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klavyenizi kullanarak gezinin"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Klavye kısayollarını öğrenin"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Dokunmatik alanınızı kullanarak gezinin"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Uygulamalar tarafından sağlanır"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ekran"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Bilinmiyor"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index fcdccdb..307fc27 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -313,7 +313,7 @@
     <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Надсилання аудіо"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button_accessibility" msgid="7604615019302091708">"відкрити налаштування надсилання аудіо"</string>
     <string name="quick_settings_bluetooth_audio_sharing_dialog_message" msgid="4251807313264307426">"Музика й відео із цього пристрою відтворюватимуться на обох парах навушників"</string>
-    <string name="quick_settings_bluetooth_audio_sharing_dialog_title" msgid="4406818346036286793">"Поділитися аудіо"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_dialog_title" msgid="4406818346036286793">"Надіслати аудіо"</string>
     <string name="quick_settings_bluetooth_audio_sharing_dialog_subtitle" msgid="3014906864710059236">"Пристрої \"<xliff:g id="AVAILABLE_DEVICE_NAME">%1$s</xliff:g>\" і \"<xliff:g id="ACTIVE_DEVICE_NAME">%2$s</xliff:g>\""</string>
     <string name="quick_settings_bluetooth_audio_sharing_dialog_switch_to_button" msgid="7546825655978203773">"Перемкнути на \"<xliff:g id="AVAILABLE_DEVICE_NAME">%1$s</xliff:g>\""</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> заряду акумулятора"</string>
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок розгортання"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"або"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер переміщення"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навігація за допомогою клавіатури"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Комбінації клавіш: докладніше"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навігація за допомогою сенсорної панелі"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Надано додатками"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Екран"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Невідомо"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index a091d30..4558486 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"آئیکن پھیلائیں"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"یا"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"گھسیٹنے کا ہینڈل"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"اپنے کی بورڈ کا استعمال کر کے نیویگیٹ کریں"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"کی بورڈ شارٹ کٹس جانیں"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"اپنے ٹچ پیڈ کا استعمال کر کے نیویگیٹ کریں"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ایپس کے ذریعہ فراہم کردہ"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ڈسپلے"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"نامعلوم"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 51dcb29..00c97b1 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Yoyish belgisi"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"yoki"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Surish dastagi"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klaviatura yordamida kezing"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Tezkor tugmalar haqida"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Sensorli panel yordamida kezing"</string>
@@ -1462,4 +1464,6 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Ilovalarga tegishli"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ekran"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Noaniq"</string>
+    <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Katakchalarni asliga qaytarish"</string>
+    <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Katakchalar asl tartibi va oʻlchamiga qaytarilsinmi?"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 98fc467..6145f7c 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Biểu tượng Mở rộng"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"hoặc"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Nút kéo"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Di chuyển bằng bàn phím"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Tìm hiểu về phím tắt"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Di chuyển bằng bàn di chuột"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Do các ứng dụng cung cấp"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Hiển thị"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Không xác định"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index cf80402..53ba179 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -441,7 +441,7 @@
     <string name="zen_modes_dialog_title" msgid="8854640808100096934">"模式"</string>
     <string name="zen_modes_dialog_done" msgid="6654130880256438950">"完成"</string>
     <string name="zen_modes_dialog_settings" msgid="2310248023728936697">"设置"</string>
-    <string name="zen_mode_on" msgid="9085304934016242591">"已开启"</string>
+    <string name="zen_mode_on" msgid="9085304934016242591">"开启"</string>
     <string name="zen_mode_on_with_details" msgid="7416143430557895497">"已开启 • <xliff:g id="TRIGGER_DESCRIPTION">%1$s</xliff:g>"</string>
     <string name="zen_mode_off" msgid="1736604456618147306">"已关闭"</string>
     <string name="zen_mode_set_up" msgid="8231201163894922821">"未设置"</string>
@@ -556,7 +556,7 @@
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"投放整个屏幕时,屏幕上的所有内容均公开可见。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"投放单个应用时,该应用显示或播放的所有内容均公开可见。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
     <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"投放屏幕"</string>
-    <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"选择要投放的应用"</string>
+    <string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"选择要投屏的应用"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"开始分享?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"在分享内容时,Android 可以访问屏幕上显示或设备中播放的所有内容。因此,请务必小心操作,谨防密码、付款信息、消息、照片、音频和视频等内容遭到泄露。"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"在分享、录制或投放内容时,Android 可以访问通过此应用显示或播放的所有内容。因此,请务必小心操作,谨防密码、付款信息、消息、照片、音频和视频等内容遭到泄露。"</string>
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展开图标"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖动手柄"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用键盘导航"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"了解键盘快捷键"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用触控板导航"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"由应用提供"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"显示"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"未知"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 39cf982..f496c41 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展開圖示"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖曳控點"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用鍵盤導覽"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"瞭解鍵盤快速鍵"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用觸控板導覽"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"由應用程式提供"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"螢幕"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"不明"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index cbde8c3..5157809 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展開圖示"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖曳控點"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用鍵盤操作"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"學習鍵盤快速鍵"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用觸控板操作"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"由應用程式提供"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"螢幕"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"不明"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 2e668c5..cd577e5 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -1405,6 +1405,8 @@
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Nweba isithonjana"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"noma"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Hudula isibambi"</string>
+    <!-- no translation found for shortcut_helper_keyboard_settings_buttons_label (6720967595915985259) -->
+    <skip />
     <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Funa usebenzisa ikhibhodi yakho"</string>
     <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Funda izinqamuleli zamakhibhodi"</string>
     <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Funa usebenzisa iphedi yokuthinta"</string>
@@ -1462,4 +1464,8 @@
     <string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Kuhlinzekwe ama-app"</string>
     <string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Bonisa"</string>
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Akwaziwa"</string>
+    <!-- no translation found for qs_edit_mode_reset_dialog_title (8841270491554460726) -->
+    <skip />
+    <!-- no translation found for qs_edit_mode_reset_dialog_content (8626426097929954027) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 209a971..87e6aa0 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1977,6 +1977,9 @@
         slowing down. Also for tutorial it should be fine to lean to the side of being more strict
         rather than not strict enough and not teaching user the proper gesture as a result.-->
     <dimen name="touchpad_recent_apps_gesture_velocity_threshold">0.05dp</dimen>
+    <!-- Normal gesture threshold is system_gestures_distance_threshold but for tutorial we can
+         exaggerate gesture, which also works much better with live tracking -->
+    <dimen name="touchpad_tutorial_gestures_distance_threshold">48dp</dimen>
 
     <!-- Broadcast dialog -->
     <dimen name="broadcast_dialog_title_img_margin_top">18dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index cdf15ca..c494e85 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -3745,6 +3745,10 @@
          use. The helper shows shortcuts in categories, which can be collapsed or expanded.
          [CHAR LIMIT=NONE] -->
     <string name="shortcut_helper_content_description_drag_handle">Drag handle</string>
+    <!-- Label on the keyboard settings button in keyboard shortcut helper, that allows user to
+         open keyboard settings while in shortcut helper. The helper is a  component that shows the
+         user which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
+    <string name="shortcut_helper_keyboard_settings_buttons_label">Keyboard Settings</string>
 
 
     <!-- Keyboard touchpad tutorial scheduler-->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index bda3453..1ab9242 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -1354,7 +1354,7 @@
 
     <style name="InternetDialog.Network">
         <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">88dp</item>
+        <item name="android:layout_height">wrap_content</item>
         <item name="android:layout_marginStart">@dimen/internet_dialog_network_layout_margin</item>
         <item name="android:layout_marginEnd">@dimen/internet_dialog_network_layout_margin</item>
         <item name="android:layout_gravity">center_vertical|start</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 2d27f1c0..6bcacd0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -32,7 +32,6 @@
 import static androidx.constraintlayout.widget.ConstraintSet.TOP;
 import static androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT;
 
-import static com.android.app.animation.InterpolatorsAndroidX.DECELERATE_QUINT;
 import static com.android.systemui.plugins.FalsingManager.LOW_PENALTY;
 
 import static java.lang.Integer.max;
@@ -271,8 +270,7 @@
         public void onBackProgressed(BackEvent event) {
             float progress = event.getProgress();
             // TODO(b/263819310): Update the interpolator to match spec.
-            float scale = MIN_BACK_SCALE
-                    +  (1 - MIN_BACK_SCALE) * (1 - DECELERATE_QUINT.getInterpolation(progress));
+            float scale = MIN_BACK_SCALE +  (1 - MIN_BACK_SCALE) * (1 - progress);
             setScale(scale);
         }
     };
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 83ab524..b3ea75d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2368,7 +2368,7 @@
         }
 
         // Take a guess at initial SIM state, battery status and PLMN until we get an update
-        mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, /* level= */ 100, /* plugged= */
+        mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, /* level= */ -1, /* plugged= */
                 0, CHARGING_POLICY_DEFAULT, /* maxChargingWattage= */0, /* present= */true);
 
         // Watch for interesting updates
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.kt b/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.kt
index fd06bb1..a55f9ff 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.kt
@@ -38,6 +38,9 @@
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.ui.view.WindowRootView
 import com.android.systemui.shade.ShadeExpansionChangeEvent
 import com.android.systemui.statusbar.NotificationShadeWindowController
 import com.android.systemui.statusbar.phone.CentralSurfaces
@@ -45,6 +48,7 @@
 import java.util.Optional
 import javax.inject.Inject
 import javax.inject.Named
+import javax.inject.Provider
 import kotlin.math.abs
 import kotlin.math.hypot
 import kotlin.math.max
@@ -74,6 +78,8 @@
     private val uiEventLogger: UiEventLogger,
     private val activityStarter: ActivityStarter,
     private val keyguardInteractor: KeyguardInteractor,
+    private val sceneInteractor: SceneInteractor,
+    private val windowRootViewProvider: Optional<Provider<WindowRootView>>,
 ) : TouchHandler {
     /** An interface for creating ValueAnimators. */
     interface ValueAnimatorCreator {
@@ -100,6 +106,8 @@
             currentScrimController = controller
         }
 
+    private val windowRootView by lazy { windowRootViewProvider.get().get() }
+
     /** Determines whether the touch handler should process touches in fullscreen swiping mode */
     private var touchAvailable = false
 
@@ -109,7 +117,7 @@
                 e1: MotionEvent?,
                 e2: MotionEvent,
                 distanceX: Float,
-                distanceY: Float
+                distanceY: Float,
             ): Boolean {
                 if (capture == null) {
                     capture =
@@ -128,6 +136,11 @@
                         expanded = false
                         // Since the user is dragging the bouncer up, set scrimmed to false.
                         currentScrimController?.show()
+
+                        if (SceneContainerFlag.isEnabled) {
+                            sceneInteractor.onRemoteUserInputStarted("bouncer touch handler")
+                            e1?.apply { windowRootView.dispatchTouchEvent(e1) }
+                        }
                     }
                 }
                 if (capture != true) {
@@ -152,20 +165,27 @@
                             /* cancelAction= */ null,
                             /* dismissShade= */ true,
                             /* afterKeyguardGone= */ true,
-                            /* deferred= */ false
+                            /* deferred= */ false,
                         )
                         return true
                     }
 
-                    // For consistency, we adopt the expansion definition found in the
-                    // PanelViewController. In this case, expansion refers to the view above the
-                    // bouncer. As that view's expansion shrinks, the bouncer appears. The bouncer
-                    // is fully hidden at full expansion (1) and fully visible when fully collapsed
-                    // (0).
-                    touchSession?.apply {
-                        val screenTravelPercentage =
-                            (abs((this@outer.y - e2.y).toDouble()) / getBounds().height()).toFloat()
-                        setPanelExpansion(1 - screenTravelPercentage)
+                    if (SceneContainerFlag.isEnabled) {
+                        windowRootView.dispatchTouchEvent(e2)
+                    } else {
+                        // For consistency, we adopt the expansion definition found in the
+                        // PanelViewController. In this case, expansion refers to the view above the
+                        // bouncer. As that view's expansion shrinks, the bouncer appears. The
+                        // bouncer
+                        // is fully hidden at full expansion (1) and fully visible when fully
+                        // collapsed
+                        // (0).
+                        touchSession?.apply {
+                            val screenTravelPercentage =
+                                (abs((this@outer.y - e2.y).toDouble()) / getBounds().height())
+                                    .toFloat()
+                            setPanelExpansion(1 - screenTravelPercentage)
+                        }
                     }
                 }
 
@@ -194,7 +214,7 @@
             ShadeExpansionChangeEvent(
                 /* fraction= */ currentExpansion,
                 /* expanded= */ expanded,
-                /* tracking= */ true
+                /* tracking= */ true,
             )
         currentScrimController?.expand(event)
     }
@@ -347,7 +367,7 @@
                     currentHeight,
                     targetHeight,
                     velocity,
-                    viewHeight
+                    viewHeight,
                 )
             } else {
                 // Shows the bouncer, i.e., fully collapses the space above the bouncer.
@@ -356,7 +376,7 @@
                     currentHeight,
                     targetHeight,
                     velocity,
-                    viewHeight
+                    viewHeight,
                 )
             }
             animator.start()
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/touch/ShadeTouchHandler.kt b/packages/SystemUI/src/com/android/systemui/ambient/touch/ShadeTouchHandler.kt
index 9da9a3a..3cf94ba 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/touch/ShadeTouchHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/ambient/touch/ShadeTouchHandler.kt
@@ -27,11 +27,15 @@
 import com.android.systemui.ambient.touch.dagger.ShadeModule
 import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.ui.view.WindowRootView
 import com.android.systemui.shade.ShadeViewController
 import com.android.systemui.statusbar.phone.CentralSurfaces
 import java.util.Optional
 import javax.inject.Inject
 import javax.inject.Named
+import javax.inject.Provider
 import kotlin.math.abs
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
@@ -49,8 +53,10 @@
     private val dreamManager: DreamManager,
     private val communalViewModel: CommunalViewModel,
     private val communalSettingsInteractor: CommunalSettingsInteractor,
+    private val sceneInteractor: SceneInteractor,
+    private val windowRootViewProvider: Optional<Provider<WindowRootView>>,
     @param:Named(ShadeModule.NOTIFICATION_SHADE_GESTURE_INITIATION_HEIGHT)
-    private val initiationHeight: Int
+    private val initiationHeight: Int,
 ) : TouchHandler {
     /**
      * Tracks whether or not we are capturing a given touch. Will be null before and after a touch.
@@ -60,6 +66,8 @@
     /** Determines whether the touch handler should process touches in fullscreen swiping mode */
     private var touchAvailable = false
 
+    private val windowRootView by lazy { windowRootViewProvider.get().get() }
+
     init {
         if (Flags.hubmodeFullscreenVerticalSwipeFix()) {
             scope.launch {
@@ -100,7 +108,7 @@
                     e1: MotionEvent?,
                     e2: MotionEvent,
                     distanceX: Float,
-                    distanceY: Float
+                    distanceY: Float,
                 ): Boolean {
                     if (capture == null) {
                         // Only capture swipes that are going downwards.
@@ -110,6 +118,10 @@
                                 if (Flags.hubmodeFullscreenVerticalSwipeFix()) touchAvailable
                                 else true
                         if (capture == true) {
+                            if (SceneContainerFlag.isEnabled) {
+                                sceneInteractor.onRemoteUserInputStarted("shade touch handler")
+                            }
+
                             // Send the initial touches over, as the input listener has already
                             // processed these touches.
                             e1?.apply { sendTouchEvent(this) }
@@ -123,7 +135,7 @@
                     e1: MotionEvent?,
                     e2: MotionEvent,
                     velocityX: Float,
-                    velocityY: Float
+                    velocityY: Float,
                 ): Boolean {
                     return capture == true
                 }
@@ -132,6 +144,11 @@
     }
 
     private fun sendTouchEvent(event: MotionEvent) {
+        if (SceneContainerFlag.isEnabled) {
+            windowRootView.dispatchTouchEvent(event)
+            return
+        }
+
         if (communalSettingsInteractor.isCommunalFlagEnabled() && !dreamManager.isDreaming) {
             // Send touches to central surfaces only when on the glanceable hub while not dreaming.
             // While sending touches where while dreaming will open the shade, the shade
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/touch/dagger/ShadeModule.java b/packages/SystemUI/src/com/android/systemui/ambient/touch/dagger/ShadeModule.java
index bc2f354..1c781d6 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/touch/dagger/ShadeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/ambient/touch/dagger/ShadeModule.java
@@ -22,8 +22,10 @@
 import com.android.systemui.ambient.touch.TouchHandler;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.ui.view.WindowRootView;
 
 import dagger.Binds;
+import dagger.BindsOptionalOf;
 import dagger.Module;
 import dagger.Provides;
 import dagger.multibindings.IntoSet;
@@ -51,6 +53,13 @@
             ShadeTouchHandler touchHandler);
 
     /**
+     * Window root view is used to send touches to the scene container. Declaring as optional as it
+     * may not be present on all SysUI variants.
+     */
+    @BindsOptionalOf
+    abstract WindowRootView bindWindowRootView();
+
+    /**
      * Provides the height of the gesture area for notification swipe down.
      */
     @Provides
diff --git a/packages/SystemUI/compose/scene/src/com/android/systemui/communal/ui/compose/CommunalSwipeDetector.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/compose/CommunalSwipeDetector.kt
similarity index 100%
rename from packages/SystemUI/compose/scene/src/com/android/systemui/communal/ui/compose/CommunalSwipeDetector.kt
rename to packages/SystemUI/src/com/android/systemui/communal/ui/compose/CommunalSwipeDetector.kt
diff --git a/packages/SystemUI/src/com/android/systemui/compose/ComposeInitializer.kt b/packages/SystemUI/src/com/android/systemui/compose/ComposeInitializer.kt
index 813e0e0..e6e474a 100644
--- a/packages/SystemUI/src/com/android/systemui/compose/ComposeInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/compose/ComposeInitializer.kt
@@ -22,7 +22,7 @@
 import androidx.lifecycle.setViewTreeLifecycleOwner
 import androidx.savedstate.SavedStateRegistryController
 import androidx.savedstate.SavedStateRegistryOwner
-import com.android.compose.animation.ViewTreeSavedStateRegistryOwner
+import androidx.savedstate.setViewTreeSavedStateRegistryOwner
 import com.android.systemui.lifecycle.ViewLifecycleOwner
 
 /**
@@ -88,13 +88,13 @@
         // Set the owners on the root. They will be reused by any ComposeView inside the root
         // hierarchy.
         root.setViewTreeLifecycleOwner(lifecycleOwner)
-        ViewTreeSavedStateRegistryOwner.set(root, savedStateRegistryOwner)
+        root.setViewTreeSavedStateRegistryOwner(savedStateRegistryOwner)
     }
 
     /** Function to be called on your window root view's [View.onDetachedFromWindow] function. */
     fun onDetachedFromWindow(root: View) {
         (root.findViewTreeLifecycleOwner() as ViewLifecycleOwner).onDestroy()
         root.setViewTreeLifecycleOwner(null)
-        ViewTreeSavedStateRegistryOwner.set(root, null)
+        root.setViewTreeSavedStateRegistryOwner(null)
     }
 }
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 2ce3e43..2c43455 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
@@ -76,7 +76,7 @@
         }
     }
 
-    abstract fun createInstanceForDisplay(displayId: Int): T
+    protected abstract fun createInstanceForDisplay(displayId: Int): T
 
     override fun start() {
         val instanceType = instanceClass.simpleName
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index 7a6ca08..1ffbbd2 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -65,7 +65,6 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
 import com.android.systemui.navigationbar.gestural.domain.GestureInteractor;
 import com.android.systemui.navigationbar.gestural.domain.TaskMatcher;
-import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
 import com.android.systemui.touch.TouchInsetManager;
 import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -503,10 +502,10 @@
         mDreamOverlayContainerViewController =
                 dreamOverlayComponent.getDreamOverlayContainerViewController();
 
-        if (!SceneContainerFlag.isEnabled()) {
-            mTouchMonitor = ambientTouchComponent.getTouchMonitor();
-            mTouchMonitor.init();
-        }
+        // Touch monitor are also used with SceneContainer. See individual touch handlers for
+        // handling of SceneContainer.
+        mTouchMonitor = ambientTouchComponent.getTouchMonitor();
+        mTouchMonitor.init();
 
         mStateController.setShouldShowComplications(shouldShowComplications());
 
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
index 12984efb..85fb90d 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
@@ -30,8 +30,10 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.DreamOverlayContainerView;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.ui.view.WindowRootView;
 import com.android.systemui.touch.TouchInsetManager;
 
+import dagger.BindsOptionalOf;
 import dagger.Module;
 import dagger.Provides;
 
@@ -54,6 +56,13 @@
     public static final String DREAM_IN_TRANSLATION_Y_DURATION =
             "dream_in_complications_translation_y_duration";
 
+    /**
+     * Window root view is used to send touches to the scene container. Declaring as optional as it
+     * may not be present on all SysUI variants.
+     */
+    @BindsOptionalOf
+    abstract WindowRootView bindWindowRootView();
+
     /** */
     @Provides
     @DreamOverlayComponent.DreamOverlayScope
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java
index 5ba780f..42a6877 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java
@@ -31,6 +31,9 @@
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor;
 import com.android.systemui.communal.domain.interactor.CommunalInteractor;
 import com.android.systemui.dreams.touch.dagger.CommunalTouchModule;
+import com.android.systemui.scene.domain.interactor.SceneInteractor;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
+import com.android.systemui.scene.ui.view.WindowRootView;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import kotlinx.coroutines.Job;
@@ -42,6 +45,7 @@
 
 import javax.inject.Inject;
 import javax.inject.Named;
+import javax.inject.Provider;
 
 /** {@link TouchHandler} responsible for handling touches to open communal hub. **/
 public class CommunalTouchHandler implements TouchHandler {
@@ -51,6 +55,8 @@
     private final CommunalInteractor mCommunalInteractor;
 
     private final ConfigurationInteractor mConfigurationInteractor;
+    private final SceneInteractor mSceneInteractor;
+    private final WindowRootView mWindowRootView;
     private Boolean mIsEnabled = false;
 
     private ArrayList<Job> mFlows = new ArrayList<>();
@@ -69,12 +75,16 @@
             @Named(CommunalTouchModule.COMMUNAL_GESTURE_INITIATION_WIDTH) int initiationWidth,
             CommunalInteractor communalInteractor,
             ConfigurationInteractor configurationInteractor,
+            SceneInteractor sceneInteractor,
+            Optional<Provider<WindowRootView>> windowRootViewProvider,
             Lifecycle lifecycle) {
         mInitiationWidth = initiationWidth;
         mCentralSurfaces = centralSurfaces;
         mLifecycle = lifecycle;
         mCommunalInteractor = communalInteractor;
         mConfigurationInteractor = configurationInteractor;
+        mSceneInteractor = sceneInteractor;
+        mWindowRootView = windowRootViewProvider.get().get();
 
         mFlows.add(collectFlow(
                 mLifecycle,
@@ -125,8 +135,15 @@
     private void handleSessionStart(CentralSurfaces surfaces, TouchSession session) {
         // Notification shade window has its own logic to be visible if the hub is open, no need to
         // do anything here other than send touch events over.
+        if (SceneContainerFlag.isEnabled()) {
+            mSceneInteractor.onRemoteUserInputStarted("communal touch handler");
+        }
         session.registerInputListener(ev -> {
-            surfaces.handleCommunalHubTouch((MotionEvent) ev);
+            if (SceneContainerFlag.isEnabled()) {
+                mWindowRootView.dispatchTouchEvent((MotionEvent) ev);
+            } else {
+                surfaces.handleCommunalHubTouch((MotionEvent) ev);
+            }
             if (ev != null && ((MotionEvent) ev).getAction() == MotionEvent.ACTION_UP) {
                 var unused = session.pop();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/education/ContextualEducationMetricsLogger.kt b/packages/SystemUI/src/com/android/systemui/education/ContextualEducationMetricsLogger.kt
new file mode 100644
index 0000000..9af259a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/education/ContextualEducationMetricsLogger.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.education
+
+import com.android.systemui.contextualeducation.GestureType
+import com.android.systemui.education.shared.model.EducationUiType
+import com.android.systemui.shared.system.SysUiStatsLog
+import javax.inject.Inject
+
+class ContextualEducationMetricsLogger @Inject constructor() {
+    fun logContextualEducationTriggered(gestureType: GestureType, uiType: EducationUiType) {
+        val statsGestureType =
+            when (gestureType) {
+                GestureType.BACK -> SysUiStatsLog.CONTEXTUAL_EDUCATION_TRIGGERED__GESTURE_TYPE__BACK
+                GestureType.HOME -> SysUiStatsLog.CONTEXTUAL_EDUCATION_TRIGGERED__GESTURE_TYPE__HOME
+                GestureType.OVERVIEW ->
+                    SysUiStatsLog.CONTEXTUAL_EDUCATION_TRIGGERED__GESTURE_TYPE__OVERVIEW
+                GestureType.ALL_APPS ->
+                    SysUiStatsLog.CONTEXTUAL_EDUCATION_TRIGGERED__GESTURE_TYPE__ALL_APPS
+            }
+
+        val statsEducationType =
+            when (uiType) {
+                EducationUiType.Toast ->
+                    SysUiStatsLog.CONTEXTUAL_EDUCATION_TRIGGERED__EDUCATION_TYPE__TOAST
+                EducationUiType.Notification ->
+                    SysUiStatsLog.CONTEXTUAL_EDUCATION_TRIGGERED__EDUCATION_TYPE__NOTIFICATION
+            }
+        SysUiStatsLog.write(
+            SysUiStatsLog.CONTEXTUAL_EDUCATION_TRIGGERED,
+            statsGestureType,
+            statsEducationType,
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
index c17f3fb..00da5b1 100644
--- a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.contextualeducation.GestureType.ALL_APPS
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.education.ContextualEducationMetricsLogger
 import com.android.systemui.education.dagger.ContextualEducationModule.EduClock
 import com.android.systemui.education.data.model.GestureEduModel
 import com.android.systemui.education.shared.model.EducationInfo
@@ -62,6 +63,7 @@
     private val userInputDeviceRepository: UserInputDeviceRepository,
     private val tutorialRepository: TutorialSchedulerRepository,
     private val overviewProxyService: OverviewProxyService,
+    private val metricsLogger: ContextualEducationMetricsLogger,
     @EduClock private val clock: Clock,
 ) : CoreStartable {
 
@@ -129,9 +131,11 @@
                     if (isUsageSessionExpired(it)) {
                         contextualEducationInteractor.startNewUsageSession(it.gestureType)
                     } else if (isEducationNeeded(it)) {
+                        val educationType = getEduType(it)
                         _educationTriggered.value =
-                            EducationInfo(it.gestureType, getEduType(it), it.userId)
+                            EducationInfo(it.gestureType, educationType, it.userId)
                         contextualEducationInteractor.updateOnEduTriggered(it.gestureType)
+                        metricsLogger.logContextualEducationTriggered(it.gestureType, educationType)
                     }
                 }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/InputDeviceTutorialLogger.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/InputDeviceTutorialLogger.kt
index 48f5cb6..b014a33 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/InputDeviceTutorialLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/InputDeviceTutorialLogger.kt
@@ -16,7 +16,9 @@
 
 package com.android.systemui.inputdevice.tutorial
 
+import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType
 import com.android.systemui.inputdevice.tutorial.domain.interactor.ConnectionState
+import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSchedulerInteractor.TutorialType
 import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen as KeyboardTouchpadTutorialScreen
 import com.android.systemui.log.ConstantStringsLogger
 import com.android.systemui.log.ConstantStringsLoggerImpl
@@ -41,7 +43,7 @@
                 str1 = screen.toString()
                 str2 = context.string
             },
-            { "Emitting new screen $str1 in $str2" }
+            { "Emitting new screen $str1 in $str2" },
         )
     }
 
@@ -58,7 +60,7 @@
             TAG,
             LogLevel.WARNING,
             { str1 = nextScreen.toString() },
-            { "next screen should be $str1 but required hardware is missing" }
+            { "next screen should be $str1 but required hardware is missing" },
         )
     }
 
@@ -72,20 +74,20 @@
                 bool1 = connectionState.touchpadConnected
                 bool2 = connectionState.keyboardConnected
             },
-            { "Received connection state: touchpad connected: $bool1 keyboard connected: $bool2" }
+            { "Received connection state: touchpad connected: $bool1 keyboard connected: $bool2" },
         )
     }
 
     fun logMovingBetweenScreens(
         previousScreen: KeyboardTouchpadTutorialScreen?,
-        currentScreen: KeyboardTouchpadTutorialScreen
+        currentScreen: KeyboardTouchpadTutorialScreen,
     ) {
         logInfo(
             {
                 str1 = previousScreen?.toString() ?: "NO_SCREEN"
                 str2 = currentScreen.toString()
             },
-            { "Moving from $str1 screen to $str2 screen" }
+            { "Moving from $str1 screen to $str2 screen" },
         )
     }
 
@@ -93,9 +95,17 @@
         logInfo({ str1 = previousScreen.toString() }, { "Going back to $str1 screen" })
     }
 
+    fun logDeviceFirstConnection(deviceType: DeviceType) {
+        logInfo({ str1 = deviceType.toString() }, { "$str1 has connected for the first time" })
+    }
+
+    fun logTutorialLaunched(tutorialType: TutorialType) {
+        logInfo({ str1 = tutorialType.toString() }, { "Launching $str1 tutorial" })
+    }
+
     private inline fun logInfo(
         messageInitializer: MessageInitializer,
-        noinline messagePrinter: MessagePrinter
+        noinline messagePrinter: MessagePrinter,
     ) {
         buffer.log(TAG, LogLevel.INFO, messageInitializer, messagePrinter)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
index cfc913f..3b4d00d 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
@@ -18,6 +18,7 @@
 
 import android.os.SystemProperties
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger
 import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType
 import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.KEYBOARD
 import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.TOUCHPAD
@@ -47,12 +48,13 @@
 constructor(
     keyboardRepository: KeyboardRepository,
     touchpadRepository: TouchpadRepository,
-    private val repo: TutorialSchedulerRepository
+    private val repo: TutorialSchedulerRepository,
+    private val logger: InputDeviceTutorialLogger,
 ) {
     private val isAnyDeviceConnected =
         mapOf(
             KEYBOARD to keyboardRepository.isAnyKeyboardConnected,
-            TOUCHPAD to touchpadRepository.isAnyTouchpadConnected
+            TOUCHPAD to touchpadRepository.isAnyTouchpadConnected,
         )
 
     private val touchpadScheduleFlow = flow {
@@ -71,10 +73,14 @@
 
     private suspend fun schedule(deviceType: DeviceType) {
         if (!repo.wasEverConnected(deviceType)) {
+            logger.d("Waiting for $deviceType to connect")
             waitForDeviceConnection(deviceType)
+            logger.logDeviceFirstConnection(deviceType)
             repo.updateFirstConnectionTime(deviceType, Instant.now())
         }
-        delay(remainingTime(start = repo.firstConnectionTime(deviceType)!!))
+        val remainingTime = remainingTime(start = repo.firstConnectionTime(deviceType)!!)
+        logger.d("Tutorial is scheduled in ${remainingTime.inWholeSeconds} seconds")
+        delay(remainingTime)
         waitForDeviceConnection(deviceType)
     }
 
@@ -92,6 +98,7 @@
             if (tutorialType == TutorialType.TOUCHPAD || tutorialType == TutorialType.BOTH)
                 repo.updateLaunchTime(TOUCHPAD, Instant.now())
 
+            logger.logTutorialLaunched(tutorialType)
             tutorialType
         }
 
@@ -119,7 +126,7 @@
                 Duration.ofSeconds(
                     SystemProperties.getLong(
                         "persist.peripheral_tutorial_delay_sec",
-                        DEFAULT_LAUNCH_DELAY_SEC
+                        DEFAULT_LAUNCH_DELAY_SEC,
                     )
                 )
     }
@@ -128,6 +135,6 @@
         KEYBOARD,
         TOUCHPAD,
         BOTH,
-        NONE
+        NONE,
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionKeyTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionKeyTutorialScreen.kt
index 4142be3..058e587 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionKeyTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionKeyTutorialScreen.kt
@@ -52,7 +52,7 @@
             Modifier.fillMaxSize()
                 .onKeyEvent { keyEvent: KeyEvent ->
                     if (keyEvent.key == Key.MetaLeft && keyEvent.type == KeyEventType.KeyUp) {
-                        actionState = Finished
+                        actionState = Finished(R.raw.action_key_success)
                     }
                     true
                 }
@@ -80,11 +80,7 @@
                 titleSuccessResId = R.string.tutorial_action_key_success_title,
                 bodySuccessResId = R.string.tutorial_action_key_success_body,
             ),
-        animations =
-            TutorialScreenConfig.Animations(
-                educationResId = R.raw.action_key_edu,
-                successResId = R.raw.action_key_success,
-            ),
+        animations = TutorialScreenConfig.Animations(educationResId = R.raw.action_key_edu),
     )
 
 @Composable
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt
index 8e01e37..3d2baee 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/ActionTutorialContent.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.inputdevice.tutorial.ui.composable
 
+import androidx.annotation.RawRes
 import androidx.annotation.StringRes
 import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.fadeIn
@@ -48,7 +49,7 @@
         val endMarker: String? = null,
     ) : TutorialActionState
 
-    data object Finished : TutorialActionState
+    data class Finished(@RawRes val successAnimation: Int) : TutorialActionState
 }
 
 @Composable
@@ -68,11 +69,11 @@
         Row(modifier = Modifier.fillMaxWidth().weight(1f)) {
             TutorialDescription(
                 titleTextId =
-                    if (actionState == Finished) config.strings.titleSuccessResId
+                    if (actionState is Finished) config.strings.titleSuccessResId
                     else config.strings.titleResId,
                 titleColor = config.colors.title,
                 bodyTextId =
-                    if (actionState == Finished) config.strings.bodySuccessResId
+                    if (actionState is Finished) config.strings.bodySuccessResId
                     else config.strings.bodyResId,
                 modifier = Modifier.weight(1f),
             )
@@ -83,7 +84,7 @@
                 modifier = Modifier.weight(1f).padding(top = 8.dp),
             )
         }
-        AnimatedVisibility(visible = actionState == Finished, enter = fadeIn()) {
+        AnimatedVisibility(visible = actionState is Finished, enter = fadeIn()) {
             DoneButton(onDoneButtonClicked = onDoneButtonClicked)
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialAnimation.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialAnimation.kt
index ef375a8..720c01f 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialAnimation.kt
@@ -77,7 +77,9 @@
                         config.colors.animationColors,
                     )
                 Finished::class ->
-                    SuccessAnimation(config.animations.successResId, config.colors.animationColors)
+                    // Below cast is safe as Finished state is the last state and afterwards we can
+                    // only leave the screen so this composable would be no longer displayed
+                    SuccessAnimation(actionState as Finished, config.colors.animationColors)
             }
         }
     }
@@ -100,10 +102,11 @@
 
 @Composable
 private fun SuccessAnimation(
-    @RawRes successAnimationId: Int,
+    finishedState: Finished,
     animationProperties: LottieDynamicProperties,
 ) {
-    val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(successAnimationId))
+    val composition by
+        rememberLottieComposition(LottieCompositionSpec.RawRes(finishedState.successAnimation))
     val progress by animateLottieCompositionAsState(composition, iterations = 1)
     LottieAnimation(
         composition = composition,
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt
index 55e5f2d..60dfed3 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/composable/TutorialScreenConfig.kt
@@ -24,13 +24,13 @@
 data class TutorialScreenConfig(
     val colors: Colors,
     val strings: Strings,
-    val animations: Animations
+    val animations: Animations,
 ) {
 
     data class Colors(
         val background: Color,
         val title: Color,
-        val animationColors: LottieDynamicProperties
+        val animationColors: LottieDynamicProperties,
     )
 
     data class Strings(
@@ -40,8 +40,5 @@
         @StringRes val bodySuccessResId: Int,
     )
 
-    data class Animations(
-        @RawRes val educationResId: Int,
-        @RawRes val successResId: Int,
-    )
+    data class Animations(@RawRes val educationResId: Int)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt
index 85bd0b0..a085887 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt
@@ -68,7 +68,7 @@
     @InputShortcuts private val inputShortcutsSource: KeyboardShortcutGroupsSource,
     @CurrentAppShortcuts private val currentAppShortcutsSource: KeyboardShortcutGroupsSource,
     private val inputManager: InputManager,
-    stateRepository: ShortcutHelperStateRepository
+    stateRepository: ShortcutHelperStateRepository,
 ) {
 
     private val sources =
@@ -76,27 +76,27 @@
             InternalGroupsSource(
                 source = systemShortcutsSource,
                 isTrusted = true,
-                typeProvider = { System }
+                typeProvider = { System },
             ),
             InternalGroupsSource(
                 source = multitaskingShortcutsSource,
                 isTrusted = true,
-                typeProvider = { MultiTasking }
+                typeProvider = { MultiTasking },
             ),
             InternalGroupsSource(
                 source = appCategoriesShortcutsSource,
                 isTrusted = true,
-                typeProvider = { AppCategories }
+                typeProvider = { AppCategories },
             ),
             InternalGroupsSource(
                 source = inputShortcutsSource,
                 isTrusted = false,
-                typeProvider = { InputMethodEditor }
+                typeProvider = { InputMethodEditor },
             ),
             InternalGroupsSource(
                 source = currentAppShortcutsSource,
                 isTrusted = false,
-                typeProvider = { groups -> getCurrentAppShortcutCategoryType(groups) }
+                typeProvider = { groups -> getCurrentAppShortcutCategoryType(groups) },
             ),
         )
 
@@ -179,7 +179,7 @@
                             shortcutGroup.items,
                             keepIcons,
                             supportedKeyCodes,
-                        )
+                        ),
                     )
                 }
                 .filter { it.shortcuts.isNotEmpty() }
@@ -214,13 +214,13 @@
         return Shortcut(
             label = shortcutInfo.label!!.toString(),
             icon = toShortcutIcon(keepIcon, shortcutInfo),
-            commands = listOf(shortcutCommand)
+            commands = listOf(shortcutCommand),
         )
     }
 
     private fun toShortcutIcon(
         keepIcon: Boolean,
-        shortcutInfo: KeyboardShortcutInfo
+        shortcutInfo: KeyboardShortcutInfo,
     ): ShortcutIcon? {
         if (!keepIcon) {
             return null
@@ -236,13 +236,13 @@
 
     private fun toShortcutCommand(
         keyCharacterMap: KeyCharacterMap,
-        info: KeyboardShortcutInfo
+        info: KeyboardShortcutInfo,
     ): ShortcutCommand? {
         val keys = mutableListOf<ShortcutKey>()
         var remainingModifiers = info.modifiers
         SUPPORTED_MODIFIERS.forEach { supportedModifier ->
             if ((supportedModifier and remainingModifiers) != 0) {
-                keys += toShortcutKey(keyCharacterMap, supportedModifier) ?: return null
+                keys += toShortcutModifierKey(supportedModifier) ?: return null
                 // "Remove" the modifier from the remaining modifiers
                 remainingModifiers = remainingModifiers and supportedModifier.inv()
             }
@@ -262,6 +262,20 @@
         return ShortcutCommand(keys)
     }
 
+    private fun toShortcutModifierKey(modifierMask: Int): ShortcutKey? {
+        val iconResId = ShortcutHelperKeys.keyIcons[modifierMask]
+        if (iconResId != null) {
+            return ShortcutKey.Icon(iconResId)
+        }
+
+        val modifierLabel = ShortcutHelperKeys.modifierLabels[modifierMask]
+        if (modifierLabel != null) {
+            return ShortcutKey.Text(modifierLabel(context))
+        }
+        Log.wtf("TAG", "Couldn't find label or icon for modifier $modifierMask")
+        return null
+    }
+
     private fun toShortcutKey(
         keyCharacterMap: KeyCharacterMap,
         keyCode: Int,
@@ -289,7 +303,7 @@
 
     private suspend fun fetchSupportedKeyCodes(
         deviceId: Int,
-        groupsFromAllSources: List<List<KeyboardShortcutGroup>>
+        groupsFromAllSources: List<List<KeyboardShortcutGroup>>,
     ): Set<Int> =
         withContext(backgroundDispatcher) {
             val allUsedKeyCodes =
@@ -320,7 +334,7 @@
                 KeyEvent.META_ALT_ON,
                 KeyEvent.META_SHIFT_ON,
                 KeyEvent.META_SYM_ON,
-                KeyEvent.META_FUNCTION_ON
+                KeyEvent.META_FUNCTION_ON,
             )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
index 8db16fa..288efa2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
@@ -124,6 +124,17 @@
             KEYCODE_RECENT_APPS to R.drawable.ic_check_box_outline_blank,
         )
 
+    val modifierLabels =
+        mapOf<Int, (Context) -> String>(
+            // Modifiers
+            META_META_ON to { "Meta" },
+            META_CTRL_ON to { "Ctrl" },
+            META_ALT_ON to { "Alt" },
+            META_SHIFT_ON to { "Shift" },
+            META_SYM_ON to { "Sym" },
+            META_FUNCTION_ON to { "Fn" },
+        )
+
     val specialKeyLabels =
         mapOf<Int, (Context) -> String>(
             KEYCODE_HOME to { context -> context.getString(R.string.keyboard_key_home) },
@@ -317,7 +328,7 @@
                 { context ->
                     context.getString(
                         R.string.keyboard_key_numpad_template,
-                        context.getString(R.string.keyboard_key_enter)
+                        context.getString(R.string.keyboard_key_enter),
                     )
                 },
             KEYCODE_NUMPAD_EQUALS to
@@ -343,13 +354,5 @@
             KEYCODE_CTRL_RIGHT to { "Ctrl" },
             KEYCODE_SHIFT_LEFT to { "Shift" },
             KEYCODE_SHIFT_RIGHT to { "Shift" },
-
-            // Modifiers
-            META_META_ON to { "Meta" },
-            META_CTRL_ON to { "Ctrl" },
-            META_ALT_ON to { "Alt" },
-            META_SHIFT_ON to { "Shift" },
-            META_SYM_ON to { "Sym" },
-            META_FUNCTION_ON to { "Fn" },
         )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
index 901eafa..5cade68 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
@@ -777,7 +777,7 @@
     ) {
         Row(verticalAlignment = Alignment.CenterVertically) {
             Text(
-                "Keyboard Settings",
+                stringResource(id = R.string.shortcut_helper_keyboard_settings_buttons_label),
                 color = MaterialTheme.colorScheme.onSurfaceVariant,
                 fontSize = 16.sp,
             )
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 0d5ad54..29c6d5a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -50,7 +50,6 @@
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.data.repository.ShadeRepository
-import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
 import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
@@ -93,7 +92,6 @@
     private val fromGoneTransitionInteractor: Provider<FromGoneTransitionInteractor>,
     private val fromLockscreenTransitionInteractor: Provider<FromLockscreenTransitionInteractor>,
     private val fromOccludedTransitionInteractor: Provider<FromOccludedTransitionInteractor>,
-    sharedNotificationContainerInteractor: Provider<SharedNotificationContainerInteractor>,
     @Application applicationScope: CoroutineScope,
 ) {
     // TODO(b/296118689): move to a repository
@@ -104,15 +102,16 @@
         SceneContainerFlag.assertInLegacyMode()
         combineTransform(
                 _notificationPlaceholderBounds,
-                sharedNotificationContainerInteractor.get().configurationBasedDimensions,
                 keyguardTransitionInteractor.isInTransition(
                     edge = Edge.create(from = LOCKSCREEN, to = AOD)
                 ),
-            ) { bounds, cfg, isTransitioningToAod ->
+                shadeRepository.isShadeLayoutWide,
+                configurationInteractor.dimensionPixelSize(R.dimen.keyguard_split_shade_top_margin),
+            ) { bounds, isTransitioningToAod, useSplitShade, keyguardSplitShadeTopMargin ->
                 if (isTransitioningToAod) {
                     // Keep bounds stable during this transition, to prevent cases like smartspace
                     // popping in and adjusting the bounds. A prime example would be media playing,
-                    // which then updates smartspace on transition to AOD
+                    // which then updates smartspace on transition to AOD.
                     return@combineTransform
                 }
 
@@ -120,8 +119,8 @@
                 // legacy placement behavior within notifications for splitshade.
                 emit(
                     if (MigrateClocksToBlueprint.isEnabled) {
-                        if (cfg.useSplitShade) {
-                            bounds.copy(bottom = bounds.bottom - cfg.keyguardSplitShadeTopMargin)
+                        if (useSplitShade) {
+                            bounds.copy(bottom = bounds.bottom - keyguardSplitShadeTopMargin)
                         } else {
                             bounds
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
index c392c2f..45ff7f4 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
@@ -18,9 +18,9 @@
 
 import com.android.internal.statusbar.RegisterStatusBarResult
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.shared.statusbar.phone.BarTransitions
 import com.android.systemui.navigationbar.views.NavigationBar
 import com.android.systemui.navigationbar.views.NavigationBarView
+import com.android.systemui.shared.statusbar.phone.BarTransitions
 import javax.inject.Inject
 
 /** A no-op version of [NavigationBarController] for variants like Arc and TV. */
@@ -30,18 +30,28 @@
         includeDefaultDisplay: Boolean,
         result: RegisterStatusBarResult?,
     ) {}
+
     override fun removeNavigationBar(displayId: Int) {}
+
     override fun checkNavBarModes(displayId: Int) {}
+
     override fun finishBarAnimations(displayId: Int) {}
+
     override fun touchAutoDim(displayId: Int) {}
+
     override fun transitionTo(
         displayId: Int,
         @BarTransitions.TransitionMode barMode: Int,
         animate: Boolean,
     ) {}
+
     override fun disableAnimationsDuringHide(displayId: Int, delay: Long) {}
+
     override fun getDefaultNavigationBarView(): NavigationBarView? = null
+
     override fun getNavigationBarView(displayId: Int): NavigationBarView? = null
+
     override fun isOverviewEnabled(displayId: Int) = false
+
     override fun getDefaultNavigationBar(): NavigationBar? = null
 }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
index e931f8f..2d00150 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
@@ -46,7 +46,7 @@
     private var arrowLength =
         AnimatedFloat(
             name = "arrowLength",
-            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS
+            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS,
         )
 
     /**
@@ -56,7 +56,7 @@
     var arrowHeight =
         AnimatedFloat(
             name = "arrowHeight",
-            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ROTATION_DEGREES
+            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ROTATION_DEGREES,
         )
 
     val backgroundWidth =
@@ -89,7 +89,7 @@
         AnimatedFloat(
             name = "scale",
             minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_SCALE,
-            minimumValue = 0f
+            minimumValue = 0f,
         )
 
     val scalePivotX =
@@ -111,7 +111,7 @@
             name = "arrowAlpha",
             minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA,
             minimumValue = 0f,
-            maximumValue = 1f
+            maximumValue = 1f,
         )
 
     val backgroundAlpha =
@@ -119,7 +119,7 @@
             name = "backgroundAlpha",
             minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA,
             minimumValue = 0f,
-            maximumValue = 1f
+            maximumValue = 1f,
         )
 
     private val allAnimatedFloat =
@@ -133,7 +133,7 @@
             scale,
             horizontalTranslation,
             arrowAlpha,
-            backgroundAlpha
+            backgroundAlpha,
         )
 
     /**
@@ -162,7 +162,7 @@
                     com.android.internal.R.attr.materialColorOnSecondaryContainer
                 } else {
                     com.android.internal.R.attr.materialColorOnSecondaryFixed
-                }
+                },
             )
 
         arrowBackgroundPaint.color =
@@ -172,7 +172,7 @@
                     com.android.internal.R.attr.materialColorSecondaryContainer
                 } else {
                     com.android.internal.R.attr.materialColorSecondaryFixedDim
-                }
+                },
             )
     }
 
@@ -242,7 +242,7 @@
         fun stretchTo(
             stretchAmount: Float,
             startingVelocity: Float? = null,
-            springForce: SpringForce? = null
+            springForce: SpringForce? = null,
         ) {
             animation.apply {
                 startingVelocity?.let {
@@ -303,7 +303,7 @@
 
     fun addAnimationEndListener(
         animatedFloat: AnimatedFloat,
-        endListener: DelayedOnAnimationEndListener
+        endListener: DelayedOnAnimationEndListener,
     ): Boolean {
         return if (animatedFloat.isRunning) {
             animatedFloat.addEndListener(endListener)
@@ -327,43 +327,43 @@
         backgroundHeightStretchAmount: Float,
         edgeCornerStretchAmount: Float,
         farCornerStretchAmount: Float,
-        fullyStretchedDimens: EdgePanelParams.BackIndicatorDimens
+        fullyStretchedDimens: EdgePanelParams.BackIndicatorDimens,
     ) {
         horizontalTranslation.stretchBy(
             finalPosition = fullyStretchedDimens.horizontalTranslation,
-            amount = horizontalTranslationStretchAmount
+            amount = horizontalTranslationStretchAmount,
         )
         arrowLength.stretchBy(
             finalPosition = fullyStretchedDimens.arrowDimens.length,
-            amount = arrowStretchAmount
+            amount = arrowStretchAmount,
         )
         arrowHeight.stretchBy(
             finalPosition = fullyStretchedDimens.arrowDimens.height,
-            amount = arrowStretchAmount
+            amount = arrowStretchAmount,
         )
         arrowAlpha.stretchBy(
             finalPosition = fullyStretchedDimens.arrowDimens.alpha,
-            amount = arrowAlphaStretchAmount
+            amount = arrowAlphaStretchAmount,
         )
         backgroundAlpha.stretchBy(
             finalPosition = fullyStretchedDimens.backgroundDimens.alpha,
-            amount = backgroundAlphaStretchAmount
+            amount = backgroundAlphaStretchAmount,
         )
         backgroundWidth.stretchBy(
             finalPosition = fullyStretchedDimens.backgroundDimens.width,
-            amount = backgroundWidthStretchAmount
+            amount = backgroundWidthStretchAmount,
         )
         backgroundHeight.stretchBy(
             finalPosition = fullyStretchedDimens.backgroundDimens.height,
-            amount = backgroundHeightStretchAmount
+            amount = backgroundHeightStretchAmount,
         )
         backgroundEdgeCornerRadius.stretchBy(
             finalPosition = fullyStretchedDimens.backgroundDimens.edgeCornerRadius,
-            amount = edgeCornerStretchAmount
+            amount = edgeCornerStretchAmount,
         )
         backgroundFarCornerRadius.stretchBy(
             finalPosition = fullyStretchedDimens.backgroundDimens.farCornerRadius,
-            amount = farCornerStretchAmount
+            amount = farCornerStretchAmount,
         )
     }
 
@@ -381,7 +381,7 @@
         arrowAlpha.stretchTo(
             stretchAmount = 0f,
             startingVelocity = startingVelocity,
-            springForce = springForce
+            springForce = springForce,
         )
     }
 
@@ -403,7 +403,7 @@
     /** Updates resting arrow and background size not accounting for stretch */
     internal fun setRestingDimens(
         restingParams: EdgePanelParams.BackIndicatorDimens,
-        animate: Boolean = true
+        animate: Boolean = true,
     ) {
         horizontalTranslation.updateRestingPosition(restingParams.horizontalTranslation)
         scale.updateRestingPosition(restingParams.scale)
@@ -417,11 +417,11 @@
         backgroundHeight.updateRestingPosition(restingParams.backgroundDimens.height, animate)
         backgroundEdgeCornerRadius.updateRestingPosition(
             restingParams.backgroundDimens.edgeCornerRadius,
-            animate
+            animate,
         )
         backgroundFarCornerRadius.updateRestingPosition(
             restingParams.backgroundDimens.farCornerRadius,
-            animate
+            animate,
         )
     }
 
@@ -483,11 +483,11 @@
                     topLeft = edgeCorner,
                     bottomLeft = edgeCorner,
                     topRight = farCorner,
-                    bottomRight = farCorner
+                    bottomRight = farCorner,
                 )
         canvas.drawPath(
             arrowBackground,
-            arrowBackgroundPaint.apply { alpha = (255 * backgroundAlpha.pos).toInt() }
+            arrowBackgroundPaint.apply { alpha = (255 * backgroundAlpha.pos).toInt() },
         )
 
         val dx = arrowLength.pos
@@ -498,7 +498,7 @@
         val arrowOffset = (backgroundWidth - dx) / 2
         canvas.translate(
             /* dx= */ arrowOffset,
-            /* dy= */ 0f /* pass 0 for the y position since the canvas was already translated */
+            /* dy= */ 0f, /* pass 0 for the y position since the canvas was already translated */
         )
 
         val arrowPointsAwayFromEdge = !arrowsPointLeft.xor(isLeftPanel)
@@ -532,7 +532,7 @@
         topLeft: Float = 0f,
         topRight: Float = 0f,
         bottomRight: Float = 0f,
-        bottomLeft: Float = 0f
+        bottomLeft: Float = 0f,
     ): Path =
         Path().apply {
             val corners =
@@ -544,7 +544,7 @@
                     bottomRight,
                     bottomRight,
                     bottomLeft,
-                    bottomLeft
+                    bottomLeft,
                 )
             addRoundRect(this@toPathWithRoundCorners, corners, Path.Direction.CW)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index d8c13b6..7e07e4d 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -124,7 +124,7 @@
                     vibratorHelper,
                     configurationController,
                     latencyTracker,
-                    interactionJankMonitor
+                    interactionJankMonitor,
                 )
                 .also { it.init() }
         }
@@ -206,7 +206,7 @@
         COMMITTED,
 
         /* back action currently cancelling, arrow soon to be GONE */
-        CANCELLED
+        CANCELLED,
     }
 
     /**
@@ -224,7 +224,7 @@
             animation: DynamicAnimation<*>,
             canceled: Boolean,
             value: Float,
-            velocity: Float
+            velocity: Float,
         ) {
             animation.removeEndListener(this)
 
@@ -421,7 +421,7 @@
                 if (
                     isPastThresholdToActive(
                         isPastThreshold = isPastStaticThreshold,
-                        dynamicDelay = entryToActiveDelayCalculation
+                        dynamicDelay = entryToActiveDelayCalculation,
                     )
                 ) {
                     updateArrowState(GestureState.ACTIVE)
@@ -437,7 +437,7 @@
                             isPastStaticThreshold &&
                                 isPastDynamicReactivationThreshold &&
                                 isWithinYActivationThreshold,
-                        delay = MIN_DURATION_INACTIVE_BEFORE_ACTIVE_ANIMATION
+                        delay = MIN_DURATION_INACTIVE_BEFORE_ACTIVE_ANIMATION,
                     )
                 ) {
                     updateArrowState(GestureState.ACTIVE)
@@ -593,7 +593,7 @@
             arrowAlphaStretchAmount = 1f,
             edgeCornerStretchAmount = 1f,
             farCornerStretchAmount = 1f,
-            fullyStretchedDimens = params.fullyStretchedIndicator
+            fullyStretchedDimens = params.fullyStretchedIndicator,
         )
     }
 
@@ -608,7 +608,7 @@
                 params.entryIndicator.arrowDimens.alphaInterpolator?.get(progress)?.value ?: 0f,
             edgeCornerStretchAmount = params.edgeCornerInterpolator.getInterpolation(progress),
             farCornerStretchAmount = params.farCornerInterpolator.getInterpolation(progress),
-            fullyStretchedDimens = params.preThresholdIndicator
+            fullyStretchedDimens = params.preThresholdIndicator,
         )
     }
 
@@ -643,7 +643,7 @@
                     ?: 0f,
             edgeCornerStretchAmount = params.edgeCornerInterpolator.getInterpolation(progress),
             farCornerStretchAmount = params.farCornerInterpolator.getInterpolation(progress),
-            fullyStretchedDimens = params.preThresholdIndicator
+            fullyStretchedDimens = params.preThresholdIndicator,
         )
     }
 
@@ -688,7 +688,7 @@
     private fun isPastThresholdToActive(
         isPastThreshold: Boolean,
         delay: Float? = null,
-        dynamicDelay: () -> Float = { delay ?: 0F }
+        dynamicDelay: () -> Float = { delay ?: 0F },
     ): Boolean {
         val resetValue = 0L
         val isPastThresholdForFirstTime = pastThresholdWhileEntryOrInactiveTime == resetValue
@@ -709,7 +709,7 @@
 
     private fun playWithBackgroundWidthAnimation(
         onEnd: DelayedOnAnimationEndListener,
-        delay: Long = 0L
+        delay: Long = 0L,
     ) {
         if (delay == 0L) {
             updateRestingArrowDimens()
@@ -871,8 +871,8 @@
                             GestureState.FLUNG -> params.activeIndicator.backgroundDimens
                             GestureState.COMMITTED -> params.committedIndicator.backgroundDimens
                             GestureState.CANCELLED -> params.cancelledIndicator.backgroundDimens
-                        }
-                )
+                        },
+                ),
         )
     }
 
@@ -970,7 +970,7 @@
                 }
                 mainHandler.postDelayed(
                     onEndSetCommittedStateListener.runnable,
-                    MIN_DURATION_FLING_ANIMATION
+                    MIN_DURATION_FLING_ANIMATION,
                 )
                 updateRestingArrowDimens()
             }
@@ -984,13 +984,13 @@
                     updateRestingArrowDimens()
                     mainHandler.postDelayed(
                         onEndSetGoneStateListener.runnable,
-                        MIN_DURATION_COMMITTED_AFTER_FLING_ANIMATION
+                        MIN_DURATION_COMMITTED_AFTER_FLING_ANIMATION,
                     )
                 } else {
                     mView.popScale(POP_ON_COMMITTED_VELOCITY)
                     mainHandler.postDelayed(
                         onAlphaEndSetGoneStateListener.runnable,
-                        MIN_DURATION_COMMITTED_ANIMATION
+                        MIN_DURATION_COMMITTED_ANIMATION,
                     )
                 }
             }
@@ -1008,14 +1008,14 @@
     private fun performDeactivatedHapticFeedback() {
         vibratorHelper.performHapticFeedback(
             mView,
-            HapticFeedbackConstants.GESTURE_THRESHOLD_DEACTIVATE
+            HapticFeedbackConstants.GESTURE_THRESHOLD_DEACTIVATE,
         )
     }
 
     private fun performActivatedHapticFeedback() {
         vibratorHelper.performHapticFeedback(
             mView,
-            HapticFeedbackConstants.GESTURE_THRESHOLD_ACTIVATE
+            HapticFeedbackConstants.GESTURE_THRESHOLD_ACTIVATE,
         )
     }
 
@@ -1075,7 +1075,7 @@
                         "xDelta=${"%.1f".format(totalTouchDeltaActive)}",
                         "xTranslation=${"%.1f".format(previousXTranslation)}",
                         "pre=${"%.0f".format(preProgress)}%",
-                        "post=${"%.0f".format(postProgress)}%"
+                        "post=${"%.0f".format(postProgress)}%",
                     )
                 val debugPaint = Paint().apply { color = Color.WHITE }
                 val debugInfoBottom = debugStrings.size * 32f + 4f
@@ -1084,7 +1084,7 @@
                     4f,
                     canvas.width.toFloat(),
                     debugStrings.size * 32f + 4f,
-                    debugPaint
+                    debugPaint,
                 )
                 debugPaint.apply {
                     color = Color.BLACK
@@ -1132,7 +1132,7 @@
     private val threshold: Float,
     private val factor: Float = 1.1f,
     private val postThreshold: T,
-    private val preThreshold: T
+    private val preThreshold: T,
 ) {
 
     data class Value<T>(val value: T, val isNewState: Boolean)
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
index db8749f..283ae7f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -16,7 +16,7 @@
         val heightSpring: SpringForce? = null,
         val lengthSpring: SpringForce? = null,
         var alphaSpring: Step<SpringForce>? = null,
-        var alphaInterpolator: Step<Float>? = null
+        var alphaInterpolator: Step<Float>? = null,
     )
 
     data class BackgroundDimens(
@@ -178,14 +178,14 @@
                 threshold = commonArrowDimensAlphaThreshold,
                 factor = commonArrowDimensAlphaFactor,
                 postThreshold = createSpring(180f, 0.9f),
-                preThreshold = createSpring(2000f, 0.6f)
+                preThreshold = createSpring(2000f, 0.6f),
             )
         val commonArrowDimensAlphaSpringInterpolator =
             Step(
                 threshold = commonArrowDimensAlphaThreshold,
                 factor = commonArrowDimensAlphaFactor,
                 postThreshold = 1f,
-                preThreshold = 0f
+                preThreshold = 0f,
             )
 
         entryIndicator =
@@ -204,7 +204,7 @@
                         lengthSpring = createSpring(600f, 0.4f),
                         heightSpring = createSpring(600f, 0.4f),
                         alphaSpring = commonArrowDimensAlphaSpring,
-                        alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
+                        alphaInterpolator = commonArrowDimensAlphaSpringInterpolator,
                     ),
                 backgroundDimens =
                     BackgroundDimens(
@@ -217,7 +217,7 @@
                         heightSpring = createSpring(1500f, 0.45f),
                         farCornerRadiusSpring = createSpring(300f, 0.5f),
                         edgeCornerRadiusSpring = createSpring(150f, 0.5f),
-                    )
+                    ),
             )
 
         activeIndicator =
@@ -235,7 +235,7 @@
                         lengthSpring = activeCommittedArrowLengthSpring,
                         heightSpring = activeCommittedArrowHeightSpring,
                         alphaSpring = commonArrowDimensAlphaSpring,
-                        alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
+                        alphaInterpolator = commonArrowDimensAlphaSpringInterpolator,
                     ),
                 backgroundDimens =
                     BackgroundDimens(
@@ -248,7 +248,7 @@
                         heightSpring = createSpring(10000f, 1f),
                         edgeCornerRadiusSpring = createSpring(2600f, 0.855f),
                         farCornerRadiusSpring = createSpring(1200f, 0.30f),
-                    )
+                    ),
             )
 
         preThresholdIndicator =
@@ -266,7 +266,7 @@
                         lengthSpring = createSpring(100f, 0.6f),
                         heightSpring = createSpring(100f, 0.6f),
                         alphaSpring = commonArrowDimensAlphaSpring,
-                        alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
+                        alphaInterpolator = commonArrowDimensAlphaSpringInterpolator,
                     ),
                 backgroundDimens =
                     BackgroundDimens(
@@ -281,7 +281,7 @@
                         heightSpring = createSpring(1500f, 0.45f),
                         farCornerRadiusSpring = createSpring(300f, 1f),
                         edgeCornerRadiusSpring = createSpring(250f, 0.5f),
-                    )
+                    ),
             )
 
         committedIndicator =
@@ -317,7 +317,7 @@
                         lengthSpring = createSpring(850f, 0.46f),
                         heightSpring = createSpring(850f, 0.46f),
                         length = activeIndicator.arrowDimens.length,
-                        height = activeIndicator.arrowDimens.height
+                        height = activeIndicator.arrowDimens.height,
                     ),
                 backgroundDimens =
                     committedIndicator.backgroundDimens.copy(
@@ -325,7 +325,7 @@
                         heightSpring = flungCommittedHeightSpring,
                         edgeCornerRadiusSpring = flungCommittedEdgeCornerSpring,
                         farCornerRadiusSpring = flungCommittedFarCornerSpring,
-                    )
+                    ),
             )
 
         cancelledIndicator =
@@ -334,7 +334,7 @@
                     entryIndicator.backgroundDimens.copy(
                         width = 0f,
                         alpha = 0f,
-                        alphaSpring = createSpring(450f, 1f)
+                        alphaSpring = createSpring(450f, 1f),
                     )
             )
 
@@ -366,7 +366,7 @@
                         heightSpring = null,
                         edgeCornerRadiusSpring = null,
                         farCornerRadiusSpring = null,
-                    )
+                    ),
             )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/domain/GestureInteractor.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/domain/GestureInteractor.kt
index 0166176..ba746cd 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/domain/GestureInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/domain/GestureInteractor.kt
@@ -55,7 +55,7 @@
 ) {
     enum class Scope {
         Local,
-        Global
+        Global,
     }
 
     private val _localGestureBlockedMatchers = MutableStateFlow<Set<TaskMatcher>>(setOf())
@@ -86,7 +86,7 @@
         combine(
             _topActivity,
             gestureRepository.gestureBlockedMatchers,
-            _localGestureBlockedMatchers.asStateFlow()
+            _localGestureBlockedMatchers.asStateFlow(),
         ) { runningTask, global, local ->
             runningTask != null && (global + local).any { it.matches(runningTask) }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt
index a5ba17b..251fd2e 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt
@@ -31,7 +31,7 @@
         isImmersiveMode: Boolean,
         isSecondaryHandleVisible: Boolean,
         currentRotation: Int,
-        startingQuickSwitchRotation: Int
+        startingQuickSwitchRotation: Int,
     ) {
         buffer.log(
             TAG,
@@ -52,7 +52,7 @@
                     "\tDelta Rotation: ${getDeltaRotation(int1, int2)}\n" +
                     "\tStarting QuickSwitch Rotation: $int1\n" +
                     "\tCurrent Rotation: $int2\n"
-            }
+            },
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt b/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
new file mode 100644
index 0000000..ffeec4e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
@@ -0,0 +1,93 @@
+/*
+ * 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.flags
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.shade.shared.flag.DualShade
+
+/** Helper for reading or using the QS Detailed View flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object QsDetailedView {
+    /** The aconfig flag name */
+    const val FLAG_NAME = Flags.FLAG_QS_TILE_DETAILED_VIEW
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Is the flag enabled */
+    @JvmStatic
+    inline val isEnabled
+        get() =
+            Flags.qsTileDetailedView() && // mainAconfigFlag
+                DualShade.isEnabled &&
+                SceneContainerFlag.isEnabled
+
+    // NOTE: Changes should also be made in getSecondaryFlags
+
+    /** The main aconfig flag. */
+    inline fun getMainAconfigFlag() = FlagToken(FLAG_NAME, Flags.qsTileDetailedView())
+
+    /** The set of secondary flags which must be enabled for qs detailed view to work properly */
+    inline fun getSecondaryFlags(): Sequence<FlagToken> =
+        sequenceOf(
+            DualShade.token
+            // NOTE: Changes should also be made in isEnabled
+        ) + SceneContainerFlag.getAllRequirements()
+
+    /** The full set of requirements for QsDetailedView */
+    inline fun getAllRequirements(): Sequence<FlagToken> {
+        return sequenceOf(getMainAconfigFlag()) + getSecondaryFlags()
+    }
+
+    /** Return all dependencies of this flag in pairs where [Pair.first] depends on [Pair.second] */
+    inline fun getFlagDependencies(): Sequence<Pair<FlagToken, FlagToken>> {
+        val mainAconfigFlag = getMainAconfigFlag()
+        return getSecondaryFlags().map { mainAconfigFlag to it }
+    }
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+
+    /** Returns a developer-readable string that describes the current requirement list. */
+    @JvmStatic
+    fun requirementDescription(): String {
+        return buildString {
+            getAllRequirements().forEach { requirement ->
+                append('\n')
+                append(if (requirement.isEnabled) "    [MET]" else "[NOT MET]")
+                append(" ${requirement.name}")
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
index ef30cbf..43fd0f5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
@@ -33,8 +33,6 @@
 import com.android.systemui.qs.panels.ui.compose.PaginatableGridLayout
 import com.android.systemui.qs.panels.ui.compose.PaginatedGridLayout
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.InfiniteGridLayout
-import com.android.systemui.qs.panels.ui.viewmodel.IconLabelVisibilityViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.IconLabelVisibilityViewModelImpl
 import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModelImpl
 import com.android.systemui.qs.panels.ui.viewmodel.QSColumnsSizeViewModelImpl
@@ -63,11 +61,6 @@
     @Binds fun bindQSColumnsViewModel(impl: QSColumnsSizeViewModelImpl): QSColumnsViewModel
 
     @Binds
-    fun bindIconLabelVisibilityViewModel(
-        impl: IconLabelVisibilityViewModelImpl
-    ): IconLabelVisibilityViewModel
-
-    @Binds
     @PaginatedBaseLayoutType
     fun bindPaginatedBaseGridLayout(impl: InfiniteGridLayout): PaginatableGridLayout
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractor.kt
deleted file mode 100644
index fe40127..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractor.kt
+++ /dev/null
@@ -1,60 +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.qs.panels.domain.interactor
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.log.LogBuffer
-import com.android.systemui.log.core.LogLevel
-import com.android.systemui.qs.panels.shared.model.PanelsLog
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.flow.stateIn
-
-@SysUISingleton
-class IconLabelVisibilityInteractor
-@Inject
-constructor(
-    private val preferencesInteractor: QSPreferencesInteractor,
-    @PanelsLog private val logBuffer: LogBuffer,
-    @Application scope: CoroutineScope,
-) {
-    val showLabels: StateFlow<Boolean> =
-        preferencesInteractor.showLabels
-            .onEach { logChange(it) }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
-    fun setShowLabels(showLabels: Boolean) {
-        preferencesInteractor.setShowLabels(showLabels)
-    }
-
-    private fun logChange(showLabels: Boolean) {
-        logBuffer.log(
-            LOG_BUFFER_ICON_TILE_LABEL_VISIBILITY_CHANGE_TAG,
-            LogLevel.DEBUG,
-            { bool1 = showLabels },
-            { "Icon tile label visibility changed: $bool1" }
-        )
-    }
-
-    private companion object {
-        const val LOG_BUFFER_ICON_TILE_LABEL_VISIBILITY_CHANGE_TAG = "IconLabelVisibilityChange"
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSPreferencesInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSPreferencesInteractor.kt
index 854e23f..22543b1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSPreferencesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSPreferencesInteractor.kt
@@ -24,13 +24,8 @@
 
 @SysUISingleton
 class QSPreferencesInteractor @Inject constructor(private val repo: QSPreferencesRepository) {
-    val showLabels: Flow<Boolean> = repo.showLabels
     val largeTilesSpecs: Flow<Set<TileSpec>> = repo.largeTilesSpecs
 
-    fun setShowLabels(showLabels: Boolean) {
-        repo.setShowLabels(showLabels)
-    }
-
     fun setLargeTilesSpecs(specs: Set<TileSpec>) {
         repo.setLargeTilesSpecs(specs)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModel.kt
deleted file mode 100644
index 12cbde2..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModel.kt
+++ /dev/null
@@ -1,41 +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.qs.panels.ui.viewmodel
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.panels.domain.interactor.IconLabelVisibilityInteractor
-import javax.inject.Inject
-import kotlinx.coroutines.flow.StateFlow
-
-interface IconLabelVisibilityViewModel {
-    val showLabels: StateFlow<Boolean>
-
-    fun setShowLabels(showLabels: Boolean)
-}
-
-@SysUISingleton
-class IconLabelVisibilityViewModelImpl
-@Inject
-constructor(
-    private val interactor: IconLabelVisibilityInteractor,
-) : IconLabelVisibilityViewModel {
-    override val showLabels: StateFlow<Boolean> = interactor.showLabels
-
-    override fun setShowLabels(showLabels: Boolean) {
-        interactor.setShowLabels(showLabels)
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
index 78212b2..0f7dafc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
@@ -30,13 +30,9 @@
 constructor(
     iconTilesViewModel: IconTilesViewModel,
     gridSizeViewModel: QSColumnsViewModel,
-    iconLabelVisibilityViewModel: IconLabelVisibilityViewModel,
     paginatedGridInteractor: PaginatedGridInteractor,
     @Application applicationScope: CoroutineScope,
-) :
-    IconTilesViewModel by iconTilesViewModel,
-    QSColumnsViewModel by gridSizeViewModel,
-    IconLabelVisibilityViewModel by iconLabelVisibilityViewModel {
+) : IconTilesViewModel by iconTilesViewModel, QSColumnsViewModel by gridSizeViewModel {
     val rows =
         paginatedGridInteractor.rows.stateIn(
             applicationScope,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
index fb406d4..1792ebd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
@@ -152,7 +152,14 @@
         recordingController.startCountdown(
             DELAY_MS,
             INTERVAL_MS,
-            pendingServiceIntent(getStartIntent(userContextProvider.userContext)),
+            pendingServiceIntent(
+                getStartIntent(
+                    userContextProvider.userContext,
+                    issueRecordingState.traceConfig,
+                    issueRecordingState.recordScreen,
+                    issueRecordingState.takeBugreport,
+                )
+            ),
             pendingServiceIntent(getStopIntent(userContextProvider.userContext)),
         )
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt
index 0c8a375..fceee5a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt
@@ -35,6 +35,7 @@
 import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.recordissue.IssueRecordingService.Companion.getStartIntent
 import com.android.systemui.recordissue.IssueRecordingService.Companion.getStopIntent
+import com.android.systemui.recordissue.IssueRecordingState
 import com.android.systemui.recordissue.RecordIssueDialogDelegate
 import com.android.systemui.recordissue.RecordIssueModule.Companion.TILE_SPEC
 import com.android.systemui.screenrecord.RecordingController
@@ -52,6 +53,7 @@
 @Inject
 constructor(
     @Main private val mainCoroutineContext: CoroutineContext,
+    private val state: IssueRecordingState,
     private val keyguardDismissUtil: KeyguardDismissUtil,
     private val keyguardStateController: KeyguardStateController,
     private val dialogTransitionAnimator: DialogTransitionAnimator,
@@ -104,8 +106,15 @@
         recordingController.startCountdown(
             DELAY_MS,
             INTERVAL_MS,
-            pendingServiceIntent(getStartIntent(userContextProvider.userContext)),
-            pendingServiceIntent(getStopIntent(userContextProvider.userContext))
+            pendingServiceIntent(
+                getStartIntent(
+                    userContextProvider.userContext,
+                    state.traceConfig,
+                    state.recordScreen,
+                    state.takeBugreport,
+                )
+            ),
+            pendingServiceIntent(getStopIntent(userContextProvider.userContext)),
         )
 
     private fun stopIssueRecordingService() =
@@ -117,6 +126,6 @@
             userContextProvider.userContext,
             RecordingService.REQUEST_CODE,
             action,
-            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
+            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
         )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
index 3f875bc..32d9ba8 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
@@ -24,11 +24,9 @@
 import android.net.Uri
 import android.os.Handler
 import android.os.IBinder
-import android.os.Looper
 import android.util.Log
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.animation.DialogTransitionAnimator
-import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.LongRunning
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
@@ -38,6 +36,9 @@
 import com.android.systemui.screenrecord.RecordingServiceStrings
 import com.android.systemui.settings.UserContextProvider
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil
+import com.android.traceur.MessageConstants.INTENT_EXTRA_TRACE_TYPE
+import com.android.traceur.PresetTraceConfigs
+import com.android.traceur.TraceConfig
 import java.util.concurrent.Executor
 import javax.inject.Inject
 
@@ -45,7 +46,6 @@
 @Inject
 constructor(
     controller: RecordingController,
-    @Background private val bgLooper: Looper,
     @LongRunning private val bgExecutor: Executor,
     @Main handler: Handler,
     uiEventLogger: UiEventLogger,
@@ -57,6 +57,7 @@
     private val issueRecordingState: IssueRecordingState,
     traceurConnectionProvider: TraceurConnection.Provider,
     iActivityManager: IActivityManager,
+    screenRecordingStartTimeStore: ScreenRecordingStartTimeStore,
 ) :
     RecordingService(
         controller,
@@ -66,6 +67,7 @@
         notificationManager,
         userContextProvider,
         keyguardDismissUtil,
+        screenRecordingStartTimeStore,
     ) {
 
     private val traceurConnection: TraceurConnection = traceurConnectionProvider.create()
@@ -80,6 +82,7 @@
             iActivityManager,
             notificationManager,
             userContextProvider,
+            screenRecordingStartTimeStore,
         )
 
     /**
@@ -109,15 +112,23 @@
         Log.d(getTag(), "handling action: ${intent?.action}")
         when (intent?.action) {
             ACTION_START -> {
-                session.start()
-                if (!issueRecordingState.recordScreen) {
+                val screenRecord = intent.getBooleanExtra(EXTRA_SCREEN_RECORD, false)
+                with(session) {
+                    traceConfig =
+                        intent.getParcelableExtra(INTENT_EXTRA_TRACE_TYPE, TraceConfig::class.java)
+                            ?: PresetTraceConfigs.getDefaultConfig()
+                    takeBugReport = intent.getBooleanExtra(EXTRA_BUG_REPORT, false)
+                    this.screenRecord = screenRecord
+                    start()
+                }
+                if (!screenRecord) {
                     // If we don't want to record the screen, the ACTION_SHOW_START_NOTIF action
                     // will circumvent the RecordingService's screen recording start code.
                     return super.onStartCommand(Intent(ACTION_SHOW_START_NOTIF), flags, startId)
                 }
             }
             ACTION_STOP,
-            ACTION_STOP_NOTIF -> session.stop(contentResolver)
+            ACTION_STOP_NOTIF -> session.stop()
             ACTION_SHARE -> {
                 session.share(
                     intent.getIntExtra(EXTRA_NOTIFICATION_ID, mNotificationId),
@@ -136,6 +147,8 @@
     companion object {
         private const val TAG = "IssueRecordingService"
         private const val CHANNEL_ID = "issue_record"
+        const val EXTRA_SCREEN_RECORD = "extra_screenRecord"
+        const val EXTRA_BUG_REPORT = "extra_bugReport"
 
         /**
          * Get an intent to stop the issue recording service.
@@ -153,8 +166,17 @@
          *
          * @param context Context from the requesting activity
          */
-        fun getStartIntent(context: Context): Intent =
-            Intent(context, IssueRecordingService::class.java).setAction(ACTION_START)
+        fun getStartIntent(
+            context: Context,
+            traceConfig: TraceConfig,
+            screenRecord: Boolean,
+            bugReport: Boolean,
+        ): Intent =
+            Intent(context, IssueRecordingService::class.java)
+                .setAction(ACTION_START)
+                .putExtra(INTENT_EXTRA_TRACE_TYPE, traceConfig)
+                .putExtra(EXTRA_SCREEN_RECORD, screenRecord)
+                .putExtra(EXTRA_BUG_REPORT, bugReport)
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt
index ad9b4fe..4353933 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt
@@ -18,15 +18,17 @@
 
 import android.app.IActivityManager
 import android.app.NotificationManager
-import android.content.ContentResolver
+import android.content.Intent
 import android.net.Uri
 import android.os.UserHandle
 import android.provider.Settings
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
 import com.android.systemui.settings.UserContextProvider
+import com.android.traceur.PresetTraceConfigs
 import java.util.concurrent.Executor
 
+private const val SHELL_PACKAGE = "com.android.shell"
 private const val NOTIFY_SESSION_ENDED_SETTING = "should_notify_trace_session_ended"
 private const val DISABLED = 0
 
@@ -46,17 +48,25 @@
     private val iActivityManager: IActivityManager,
     private val notificationManager: NotificationManager,
     private val userContextProvider: UserContextProvider,
+    private val startTimeStore: ScreenRecordingStartTimeStore,
 ) {
+    var takeBugReport = false
+    var traceConfig = PresetTraceConfigs.getDefaultConfig()
+    var screenRecord = false
 
     fun start() {
-        bgExecutor.execute { traceurConnection.startTracing(issueRecordingState.traceConfig) }
+        bgExecutor.execute { traceurConnection.startTracing(traceConfig) }
         issueRecordingState.isRecording = true
     }
 
-    fun stop(contentResolver: ContentResolver) {
+    fun stop() {
         bgExecutor.execute {
-            if (issueRecordingState.traceConfig.longTrace) {
-                Settings.Global.putInt(contentResolver, NOTIFY_SESSION_ENDED_SETTING, DISABLED)
+            if (traceConfig.longTrace) {
+                Settings.Global.putInt(
+                    userContextProvider.userContext.contentResolver,
+                    NOTIFY_SESSION_ENDED_SETTING,
+                    DISABLED,
+                )
             }
             traceurConnection.stopTracing()
         }
@@ -70,11 +80,24 @@
                 notificationId,
                 UserHandle(userContextProvider.userContext.userId),
             )
-
-            if (issueRecordingState.takeBugreport) {
-                iActivityManager.requestBugReportWithExtraAttachment(screenRecording)
+            val screenRecordingUris: List<Uri> =
+                mutableListOf<Uri>().apply {
+                    screenRecording?.let { add(it) }
+                    if (traceConfig.winscope && screenRecord) {
+                        startTimeStore.getFileUri(userContextProvider.userContext)?.let { add(it) }
+                    }
+                }
+            if (takeBugReport) {
+                screenRecordingUris.forEach {
+                    userContextProvider.userContext.grantUriPermission(
+                        SHELL_PACKAGE,
+                        it,
+                        Intent.FLAG_GRANT_READ_URI_PERMISSION,
+                    )
+                }
+                iActivityManager.requestBugReportWithExtraAttachments(screenRecordingUris)
             } else {
-                traceurConnection.shareTraces(screenRecording)
+                traceurConnection.shareTraces(screenRecordingUris)
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStore.kt b/packages/SystemUI/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStore.kt
new file mode 100644
index 0000000..5d8bc55
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStore.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.recordissue
+
+import android.content.Context
+import android.net.Uri
+import android.os.SystemClock
+import android.util.Log
+import android.util.SparseArray
+import androidx.annotation.VisibleForTesting
+import androidx.core.content.FileProvider
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.settings.UserTracker
+import java.io.File
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+import org.json.JSONObject
+
+private const val TAG = "ScreenRecordingStartTimeStore"
+@VisibleForTesting const val REAL_TO_ELAPSED_TIME_OFFSET_NANOS_KEY = "realToElapsedTimeOffsetNanos"
+@VisibleForTesting const val ELAPSED_REAL_TIME_NANOS_KEY = "elapsedRealTimeNanos"
+private const val RECORDING_METADATA_FILE_SUFFIX = "screen_recording_metadata.json"
+private const val AUTHORITY = "com.android.systemui.fileprovider"
+
+@SysUISingleton
+class ScreenRecordingStartTimeStore @Inject constructor(private val userTracker: UserTracker) {
+    @VisibleForTesting val userIdToScreenRecordingStartTime = SparseArray<JSONObject>()
+
+    fun markStartTime() {
+        val elapsedRealTimeNano = SystemClock.elapsedRealtimeNanos()
+        val realToElapsedTimeOffsetNano =
+            TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()) -
+                SystemClock.elapsedRealtimeNanos()
+        val startTimeMetadata =
+            JSONObject()
+                .put(ELAPSED_REAL_TIME_NANOS_KEY, elapsedRealTimeNano)
+                .put(REAL_TO_ELAPSED_TIME_OFFSET_NANOS_KEY, realToElapsedTimeOffsetNano)
+        userIdToScreenRecordingStartTime.put(userTracker.userId, startTimeMetadata)
+    }
+
+    /**
+     * Outputs start time metadata as Json to a file that can then be shared. Returns the Uri or
+     * null if the file system is not usable and the start time meta data is available. Uses
+     * com.android.systemui.fileprovider's authority.
+     *
+     * Because this file is not uniquely named, it doesn't need to be cleaned up. Every time it is
+     * outputted, it will overwrite the last file's contents. This is a feature, not a bug.
+     */
+    fun getFileUri(context: Context): Uri? {
+        val dir = context.externalCacheDir?.apply { mkdirs() } ?: return null
+        try {
+            val outFile =
+                File(dir, RECORDING_METADATA_FILE_SUFFIX).apply {
+                    userIdToScreenRecordingStartTime.get(userTracker.userId)?.let {
+                        writeText(it.toString())
+                    } ?: return null
+                }
+            return FileProvider.getUriForFile(context, AUTHORITY, outFile)
+        } catch (e: Exception) {
+            Log.e(TAG, "failed to get screen recording start time metadata via file uri", e)
+            return null
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt
index 81529b3..e6df3cd 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt
@@ -76,8 +76,9 @@
     @WorkerThread fun stopTracing() = sendMessage(MessageConstants.STOP_WHAT)
 
     @WorkerThread
-    fun shareTraces(screenRecord: Uri?) {
-        val replyHandler = Messenger(ShareFilesHandler(screenRecord, userContextProvider, bgLooper))
+    fun shareTraces(screenRecordingUris: List<Uri>) {
+        val replyHandler =
+            Messenger(ShareFilesHandler(screenRecordingUris, userContextProvider, bgLooper))
         sendMessage(MessageConstants.SHARE_WHAT, replyTo = replyHandler)
     }
 
@@ -101,7 +102,7 @@
 }
 
 private class ShareFilesHandler(
-    private val screenRecord: Uri?,
+    private val screenRecordingUris: List<Uri>,
     private val userContextProvider: UserContextProvider,
     looper: Looper,
 ) : Handler(looper) {
@@ -122,7 +123,7 @@
             ArrayList<Uri>().apply {
                 perfetto?.let { add(it) }
                 winscope?.let { add(it) }
-                screenRecord?.let { add(it) }
+                screenRecordingUris.forEach { add(it) }
             }
         val fileSharingIntent =
             FileSender.buildSendIntent(userContextProvider.userContext, uris)
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index c3de067..5028c2e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -43,6 +43,7 @@
 import com.android.systemui.dagger.qualifiers.LongRunning;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget;
+import com.android.systemui.recordissue.ScreenRecordingStartTimeStore;
 import com.android.systemui.res.R;
 import com.android.systemui.screenrecord.ScreenMediaRecorder.ScreenMediaRecorderListener;
 import com.android.systemui.settings.UserContextProvider;
@@ -92,6 +93,7 @@
     private boolean mShowTaps;
     private boolean mOriginalShowTaps;
     private ScreenMediaRecorder mRecorder;
+    private final ScreenRecordingStartTimeStore mScreenRecordingStartTimeStore;
     private final Executor mLongExecutor;
     private final UiEventLogger mUiEventLogger;
     protected final NotificationManager mNotificationManager;
@@ -103,7 +105,8 @@
     public RecordingService(RecordingController controller, @LongRunning Executor executor,
             @Main Handler handler, UiEventLogger uiEventLogger,
             NotificationManager notificationManager,
-            UserContextProvider userContextTracker, KeyguardDismissUtil keyguardDismissUtil) {
+            UserContextProvider userContextTracker, KeyguardDismissUtil keyguardDismissUtil,
+            ScreenRecordingStartTimeStore screenRecordingStartTimeStore) {
         mController = controller;
         mLongExecutor = executor;
         mMainHandler = handler;
@@ -111,6 +114,7 @@
         mNotificationManager = notificationManager;
         mUserContextTracker = userContextTracker;
         mKeyguardDismissUtil = keyguardDismissUtil;
+        mScreenRecordingStartTimeStore = screenRecordingStartTimeStore;
     }
 
     /**
@@ -178,7 +182,8 @@
                         currentUid,
                         mAudioSource,
                         captureTarget,
-                        this
+                        this,
+                        mScreenRecordingStartTimeStore
                 );
 
                 if (startRecording()) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
index e024710..54da1b0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
@@ -55,6 +55,7 @@
 
 import com.android.internal.R;
 import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget;
+import com.android.systemui.recordissue.ScreenRecordingStartTimeStore;
 
 import java.io.Closeable;
 import java.io.File;
@@ -91,6 +92,7 @@
     private ScreenInternalAudioRecorder mAudio;
     private ScreenRecordingAudioSource mAudioSource;
     private final MediaProjectionCaptureTarget mCaptureRegion;
+    private final ScreenRecordingStartTimeStore mScreenRecordingStartTimeStore;
     private final Handler mHandler;
 
     private Context mContext;
@@ -99,13 +101,15 @@
     public ScreenMediaRecorder(Context context, Handler handler,
             int uid, ScreenRecordingAudioSource audioSource,
             MediaProjectionCaptureTarget captureRegion,
-            ScreenMediaRecorderListener listener) {
+            ScreenMediaRecorderListener listener,
+            ScreenRecordingStartTimeStore screenRecordingStartTimeStore) {
         mContext = context;
         mHandler = handler;
         mUid = uid;
         mCaptureRegion = captureRegion;
         mListener = listener;
         mAudioSource = audioSource;
+        mScreenRecordingStartTimeStore = screenRecordingStartTimeStore;
     }
 
     private void prepare() throws IOException, RemoteException, RuntimeException {
@@ -278,6 +282,7 @@
         Log.d(TAG, "start recording");
         prepare();
         mMediaRecorder.start();
+        mScreenRecordingStartTimeStore.markStartTime();
         recordInternalAudio();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt
index 1fcb70c..91627d6 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt
@@ -2,9 +2,9 @@
 
 import android.content.Context
 import android.view.DisplayCutout
-import com.android.systemui.res.R
 import com.android.systemui.battery.BatteryMeterView
-import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore
 import javax.inject.Inject
 
 /**
@@ -15,9 +15,11 @@
 @Inject
 constructor(
     private val context: Context,
-    private val insetsProvider: StatusBarContentInsetsProvider,
+    insetsProviderStore: StatusBarContentInsetsProviderStore,
 ) {
 
+    private val insetsProvider = insetsProviderStore.defaultDisplay
+
     private companion object {
         // MotionLayout frames are in [0, 100]. Where 0 and 100 are reserved for start and end
         // frames.
@@ -65,6 +67,5 @@
     private fun hasCenterCutout(cutout: DisplayCutout?): Boolean =
         cutout?.let {
             !insetsProvider.currentRotationHasCornerCutout() && !it.boundingRectTop.isEmpty
-        }
-            ?: false
+        } ?: false
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
new file mode 100644
index 0000000..c72db56
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.shade
+
+import android.content.Context
+import android.content.res.Resources
+import android.view.LayoutInflater
+import android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
+import com.android.systemui.Flags
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.res.R
+import dagger.Module
+import dagger.Provides
+
+/**
+ * Module responsible for managing display-specific components and resources for the notification
+ * shade window.
+ *
+ * This isolation is crucial because when the window transitions between displays, its associated
+ * context, resources, and display characteristics (like density and size) also change. If the shade
+ * window shared the same context as the rest of the system UI, it could lead to inconsistencies and
+ * errors due to incorrect display information.
+ *
+ * By using this dedicated module, we ensure the notification shade window always utilizes the
+ * correct display context and resources, regardless of the display it's on.
+ */
+@Module
+object ShadeDisplayAwareModule {
+
+    /** Creates a new context for the shade window. */
+    @Provides
+    @ShadeDisplayAware
+    @SysUISingleton
+    fun provideShadeDisplayAwareContext(context: Context): Context {
+        return if (Flags.shadeWindowGoesAround()) {
+            context
+                .createWindowContext(context.display, TYPE_APPLICATION_OVERLAY, /* options= */ null)
+                .apply { setTheme(R.style.Theme_SystemUI) }
+        } else {
+            context
+        }
+    }
+
+    @Provides
+    @ShadeDisplayAware
+    @SysUISingleton
+    fun provideShadeDisplayAwareResources(@ShadeDisplayAware context: Context): Resources {
+        return context.resources
+    }
+
+    @Provides
+    @ShadeDisplayAware
+    @SysUISingleton
+    fun providesDisplayAwareLayoutInflater(@ShadeDisplayAware context: Context): LayoutInflater {
+        return LayoutInflater.from(context)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
index cb589aa..d0f0386 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
@@ -57,7 +57,7 @@
 import com.android.systemui.shade.ShadeViewProviderModule.Companion.SHADE_HEADER
 import com.android.systemui.shade.carrier.ShadeCarrierGroup
 import com.android.systemui.shade.carrier.ShadeCarrierGroupController
-import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore
 import com.android.systemui.statusbar.phone.StatusBarLocation
 import com.android.systemui.statusbar.phone.StatusIconContainer
 import com.android.systemui.statusbar.phone.StatusOverlayHoverListenerFactory
@@ -90,7 +90,7 @@
     private val statusBarIconController: StatusBarIconController,
     private val tintedIconManagerFactory: TintedIconManager.Factory,
     private val privacyIconsController: HeaderPrivacyIconsController,
-    private val insetsProvider: StatusBarContentInsetsProvider,
+    private val insetsProviderStore: StatusBarContentInsetsProviderStore,
     private val configurationController: ConfigurationController,
     private val variableDateViewControllerFactory: VariableDateViewController.Factory,
     @Named(SHADE_HEADER) private val batteryMeterViewController: BatteryMeterViewController,
@@ -104,6 +104,8 @@
     private val statusOverlayHoverListenerFactory: StatusOverlayHoverListenerFactory,
 ) : ViewController<View>(header), Dumpable {
 
+    private val insetsProvider = insetsProviderStore.defaultDisplay
+
     companion object {
         /** IDs for transitions and constraints for the [MotionLayout]. */
         @VisibleForTesting internal val HEADER_TRANSITION_ID = R.id.header_transition
@@ -262,7 +264,7 @@
                     left,
                     header.paddingTop,
                     header.paddingRight,
-                    header.paddingBottom
+                    header.paddingBottom,
                 )
                 systemIconsHoverContainer.setPaddingRelative(
                     resources.getDimensionPixelSize(
@@ -276,7 +278,7 @@
                     ),
                     resources.getDimensionPixelSize(
                         R.dimen.hover_system_icons_container_padding_bottom
-                    )
+                    ),
                 )
             }
 
@@ -317,7 +319,7 @@
         batteryIcon.updateColors(
             fgColor /* foreground */,
             bgColor /* background */,
-            fgColor /* single tone (current default) */
+            fgColor, /* single tone (current default) */
         )
 
         carrierIconSlots =
@@ -426,7 +428,7 @@
                 if (view.isLayoutRtl) cutoutRight else cutoutLeft,
                 header.paddingStart,
                 if (view.isLayoutRtl) cutoutLeft else cutoutRight,
-                header.paddingEnd
+                header.paddingEnd,
             )
 
         if (cutout != null) {
@@ -437,7 +439,7 @@
                 changes +=
                     combinedShadeHeadersConstraintManager.centerCutoutConstraints(
                         view.isLayoutRtl,
-                        (view.width - view.paddingLeft - view.paddingRight - topCutout.width()) / 2
+                        (view.width - view.paddingLeft - view.paddingRight - topCutout.width()) / 2,
                     )
             }
         } else {
@@ -563,7 +565,7 @@
             clockPaddingStart,
             clock.paddingTop,
             clockPaddingEnd,
-            clock.paddingBottom
+            clock.paddingBottom,
         )
     }
 
@@ -602,9 +604,8 @@
 
     @VisibleForTesting internal fun simulateViewDetached() = this.onViewDetached()
 
-    inner class CustomizerAnimationListener(
-        private val enteringCustomizing: Boolean,
-    ) : AnimatorListenerAdapter() {
+    inner class CustomizerAnimationListener(private val enteringCustomizing: Boolean) :
+        AnimatorListenerAdapter() {
         override fun onAnimationEnd(animation: Animator) {
             super.onAnimationEnd(animation)
             header.animate().setListener(null)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
index 2348a11..6f5547a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
@@ -49,7 +49,10 @@
 import javax.inject.Provider
 
 /** Module for classes related to the notification shade. */
-@Module(includes = [StartShadeModule::class, ShadeViewProviderModule::class])
+@Module(
+    includes =
+        [StartShadeModule::class, ShadeViewProviderModule::class, ShadeDisplayAwareModule::class]
+)
 abstract class ShadeModule {
     companion object {
         @Provides
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt
index 0902c39..a1c3692 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt
@@ -24,7 +24,6 @@
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.data.repository.ShadeRepository
-import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.currentCoroutineContext
@@ -45,7 +44,6 @@
 constructor(
     @Application val scope: CoroutineScope,
     keyguardRepository: KeyguardRepository,
-    sharedNotificationContainerInteractor: SharedNotificationContainerInteractor,
     repository: ShadeRepository,
 ) : BaseShadeInteractor {
     init {
@@ -62,17 +60,17 @@
                 keyguardRepository.statusBarState,
                 repository.legacyShadeExpansion,
                 repository.qsExpansion,
-                sharedNotificationContainerInteractor.isSplitShadeEnabled,
+                repository.isShadeLayoutWide,
             ) {
                 lockscreenShadeExpansion,
                 statusBarState,
                 legacyShadeExpansion,
                 qsExpansion,
-                splitShadeEnabled ->
+                isShadeLayoutWide ->
                 when (statusBarState) {
                     // legacyShadeExpansion is 1 instead of 0 when QS is expanded
                     StatusBarState.SHADE ->
-                        if (!splitShadeEnabled && qsExpansion > 0f) 1f - qsExpansion
+                        if (!isShadeLayoutWide && qsExpansion > 0f) 1f - qsExpansion
                         else legacyShadeExpansion
                     StatusBarState.KEYGUARD -> lockscreenShadeExpansion
                     // dragDownAmount, which drives lockscreenShadeExpansion resets to 0f when
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index f99d8f1..520cbf9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -214,7 +214,7 @@
     private boolean mEnableBatteryDefender;
     private boolean mIncompatibleCharger;
     private int mChargingWattage;
-    private int mBatteryLevel;
+    private int mBatteryLevel = -1;
     private boolean mBatteryPresent = true;
     protected long mChargingTimeRemaining;
     private Pair<String, BiometricSourceType> mBiometricErrorMessageToShowOnScreenOn;
@@ -1032,12 +1032,16 @@
             } else if (!TextUtils.isEmpty(mTransientIndication)) {
                 newIndication = mTransientIndication;
             } else if (!mBatteryPresent) {
-                // If there is no battery detected, hide the indication and bail
+                // If there is no battery detected, hide the indication area and bail
                 mIndicationArea.setVisibility(GONE);
                 return;
             } else if (!TextUtils.isEmpty(mAlignmentIndication)) {
                 useMisalignmentColor = true;
                 newIndication = mAlignmentIndication;
+            } else if (mBatteryLevel == -1) {
+                // If the battery level is not initialized, hide the indication area
+                mIndicationArea.setVisibility(GONE);
+                return;
             } else if (mPowerPluggedIn || mEnableBatteryDefender) {
                 newIndication = computePowerIndication();
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
index e6270b8..c416bf7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
@@ -18,6 +18,7 @@
 import com.android.systemui.statusbar.data.repository.KeyguardStatusBarRepositoryModule
 import com.android.systemui.statusbar.data.repository.RemoteInputRepositoryModule
 import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerModule
+import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStoreModule
 import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryModule
 import com.android.systemui.statusbar.phone.data.StatusBarPhoneDataLayerModule
 import dagger.Module
@@ -28,6 +29,7 @@
             KeyguardStatusBarRepositoryModule::class,
             RemoteInputRepositoryModule::class,
             StatusBarConfigurationControllerModule::class,
+            StatusBarContentInsetsProviderStoreModule::class,
             StatusBarModeRepositoryModule::class,
             StatusBarPhoneDataLayerModule::class,
         ]
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
new file mode 100644
index 0000000..e471b12
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt
@@ -0,0 +1,119 @@
+/*
+ * 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.data.repository
+
+import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
+import com.android.systemui.CameraProtectionLoaderImpl
+import com.android.systemui.CoreStartable
+import com.android.systemui.SysUICutoutProviderImpl
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.display.data.repository.DisplayRepository
+import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
+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.core.StatusBarConnectedDisplays
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProviderImpl
+import dagger.Lazy
+import dagger.Module
+import dagger.Provides
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+
+/** Provides per display instances of [StatusBarContentInsetsProvider]. */
+interface StatusBarContentInsetsProviderStore : PerDisplayStore<StatusBarContentInsetsProvider>
+
+@SysUISingleton
+class MultiDisplayStatusBarContentInsetsProviderStore
+@Inject
+constructor(
+    @Background backgroundApplicationScope: CoroutineScope,
+    displayRepository: DisplayRepository,
+    private val factory: StatusBarContentInsetsProviderImpl.Factory,
+    private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
+    private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
+    private val sysUICutoutProviderFactory: SysUICutoutProviderImpl.Factory,
+    private val cameraProtectionLoaderFactory: CameraProtectionLoaderImpl.Factory,
+) :
+    StatusBarContentInsetsProviderStore,
+    PerDisplayStoreImpl<StatusBarContentInsetsProvider>(
+        backgroundApplicationScope,
+        displayRepository,
+    ) {
+
+    override fun createInstanceForDisplay(displayId: Int): StatusBarContentInsetsProvider {
+        val context = displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR).context
+        val cameraProtectionLoader = cameraProtectionLoaderFactory.create(context)
+        return factory
+            .create(
+                context,
+                statusBarConfigurationControllerStore.forDisplay(displayId),
+                sysUICutoutProviderFactory.create(context, cameraProtectionLoader),
+            )
+            .also { it.start() }
+    }
+
+    override suspend fun onDisplayRemovalAction(instance: StatusBarContentInsetsProvider) {
+        instance.stop()
+    }
+
+    override val instanceClass = StatusBarContentInsetsProvider::class.java
+}
+
+@SysUISingleton
+class SingleDisplayStatusBarContentInsetsProviderStore
+@Inject
+constructor(statusBarContentInsetsProvider: StatusBarContentInsetsProvider) :
+    StatusBarContentInsetsProviderStore,
+    PerDisplayStore<StatusBarContentInsetsProvider> by SingleDisplayStore(
+        defaultInstance = statusBarContentInsetsProvider
+    )
+
+@Module
+object StatusBarContentInsetsProviderStoreModule {
+
+    @Provides
+    @SysUISingleton
+    @IntoMap
+    @ClassKey(StatusBarContentInsetsProviderStore::class)
+    fun storeAsCoreStartable(
+        multiDisplayLazy: Lazy<MultiDisplayStatusBarContentInsetsProviderStore>
+    ): CoreStartable {
+        return if (StatusBarConnectedDisplays.isEnabled) {
+            return multiDisplayLazy.get()
+        } else {
+            CoreStartable.NOP
+        }
+    }
+
+    @Provides
+    @SysUISingleton
+    fun store(
+        singleDisplayLazy: Lazy<SingleDisplayStatusBarContentInsetsProviderStore>,
+        multiDisplayLazy: Lazy<MultiDisplayStatusBarContentInsetsProviderStore>,
+    ): StatusBarContentInsetsProviderStore {
+        return if (StatusBarConnectedDisplays.isEnabled) {
+            multiDisplayLazy.get()
+        } else {
+            singleDisplayLazy.get()
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
index 0eef8d6..2506c95 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.StatusBarState.SHADE
 import com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED
+import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsChangedListener
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import com.android.systemui.statusbar.policy.ConfigurationController
@@ -730,8 +731,12 @@
         factory: PrivacyDotViewControllerImpl.Factory,
         @Application scope: CoroutineScope,
         configurationController: ConfigurationController,
-        contentInsetsProvider: StatusBarContentInsetsProvider,
+        contentInsetsProviderStore: StatusBarContentInsetsProviderStore,
     ): PrivacyDotViewController {
-        return factory.create(scope, configurationController, contentInsetsProvider)
+        return factory.create(
+            scope,
+            configurationController,
+            contentInsetsProviderStore.defaultDisplay,
+        )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
index 35816c2..b286605 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
@@ -33,6 +33,7 @@
 import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.res.R
+import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsChangedListener
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import com.android.systemui.statusbar.window.StatusBarWindowController
@@ -453,12 +454,12 @@
         factory: SystemEventChipAnimationControllerImpl.Factory,
         context: Context,
         statusBarWindowControllerStore: StatusBarWindowControllerStore,
-        contentInsetsProvider: StatusBarContentInsetsProvider,
+        contentInsetsProviderStore: StatusBarContentInsetsProviderStore,
     ): SystemEventChipAnimationController {
         return factory.create(
             context,
             statusBarWindowControllerStore.defaultDisplay,
-            contentInsetsProvider,
+            contentInsetsProviderStore.defaultDisplay,
         )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
index c6f3d7d..564d52a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -16,17 +16,19 @@
 
 package com.android.systemui.statusbar.events
 
-import android.annotation.IntDef
 import androidx.core.animation.Animator
 import androidx.core.animation.AnimatorSet
 import androidx.core.animation.PathInterpolator
 import com.android.systemui.Dumpable
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState
 import com.android.systemui.statusbar.policy.CallbackController
+import kotlinx.coroutines.flow.StateFlow
 
 interface SystemStatusAnimationScheduler :
     CallbackController<SystemStatusAnimationCallback>, Dumpable {
 
-    @SystemAnimationState fun getAnimationState(): Int
+    /** StateFlow holding the current [SystemEventAnimationState] at any time. */
+    val animationState: StateFlow<SystemEventAnimationState>
 
     fun onStatusEvent(event: StatusEvent)
 
@@ -63,34 +65,6 @@
     }
 }
 
-/** Animation state IntDef */
-@Retention(AnnotationRetention.SOURCE)
-@IntDef(
-    value =
-        [
-            IDLE,
-            ANIMATION_QUEUED,
-            ANIMATING_IN,
-            RUNNING_CHIP_ANIM,
-            ANIMATING_OUT,
-            SHOWING_PERSISTENT_DOT,
-        ]
-)
-annotation class SystemAnimationState
-
-/** No animation is in progress */
-@SystemAnimationState const val IDLE = 0
-/** An animation is queued, and awaiting the debounce period */
-const val ANIMATION_QUEUED = 1
-/** System is animating out, and chip is animating in */
-const val ANIMATING_IN = 2
-/** Chip has animated in and is awaiting exit animation, and optionally playing its own animation */
-const val RUNNING_CHIP_ANIM = 3
-/** Chip is animating away and system is animating back */
-const val ANIMATING_OUT = 4
-/** Chip has animated away, and the persistent dot is showing */
-const val SHOWING_PERSISTENT_DOT = 5
-
 /** Commonly-needed interpolators can go here */
 @JvmField val STATUS_BAR_X_MOVE_OUT = PathInterpolator(0.33f, 0f, 0f, 1f)
 @JvmField val STATUS_BAR_X_MOVE_IN = PathInterpolator(0f, 0f, 0f, 1f)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt
index 5f9e426..5ff4423 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt
@@ -23,6 +23,12 @@
 import androidx.core.animation.AnimatorSet
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingIn
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingOut
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimationQueued
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.RunningChipAnim
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.ShowingPersistentDot
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
 import com.android.systemui.util.Assert
 import com.android.systemui.util.time.SystemClock
@@ -33,6 +39,7 @@
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.debounce
 import kotlinx.coroutines.flow.first
@@ -85,8 +92,8 @@
      */
     private var currentlyDisplayedEvent: StatusEvent? = null
 
-    /** StateFlow holding the current [SystemAnimationState] at any time. */
-    private var animationState = MutableStateFlow(IDLE)
+    private val _animationState = MutableStateFlow(Idle)
+    override val animationState = _animationState.asStateFlow()
 
     /** True if the persistent privacy dot should be active */
     var hasPersistentDot = false
@@ -109,24 +116,22 @@
             // Wait for animationState to become ANIMATION_QUEUED and scheduledEvent to be non null.
             // Once this combination is stable for at least DEBOUNCE_DELAY, then start a chip enter
             // animation
-            animationState
+            _animationState
                 .combine(scheduledEvent) { animationState, scheduledEvent ->
                     Pair(animationState, scheduledEvent)
                 }
                 .debounce(DEBOUNCE_DELAY)
                 .collect { (animationState, event) ->
-                    if (animationState == ANIMATION_QUEUED && event != null) {
+                    if (animationState == AnimationQueued && event != null) {
                         startAnimationLifecycle(event)
                         scheduledEvent.value = null
                     }
                 }
         }
 
-        coroutineScope.launch { animationState.collect { logger?.logAnimationStateUpdate(it) } }
+        coroutineScope.launch { _animationState.collect { logger?.logAnimationStateUpdate(it) } }
     }
 
-    @SystemAnimationState override fun getAnimationState(): Int = animationState.value
-
     override fun onStatusEvent(event: StatusEvent) {
         Assert.isMainThread()
 
@@ -146,11 +151,11 @@
             logger?.logScheduleEvent(event)
             scheduleEvent(event)
         } else if (currentlyDisplayedEvent?.shouldUpdateFromEvent(event) == true) {
-            logger?.logUpdateEvent(event, animationState.value)
+            logger?.logUpdateEvent(event, _animationState.value)
             currentlyDisplayedEvent?.updateFromEvent(event)
             if (event.forceVisible) hasPersistentDot = true
         } else if (scheduledEvent.value?.shouldUpdateFromEvent(event) == true) {
-            logger?.logUpdateEvent(event, animationState.value)
+            logger?.logUpdateEvent(event, _animationState.value)
             scheduledEvent.value?.updateFromEvent(event)
         } else {
             logger?.logIgnoreEvent(event)
@@ -170,15 +175,15 @@
         // the disappear animation will not animate into a dot but remove the chip entirely
         hasPersistentDot = false
 
-        if (animationState.value == SHOWING_PERSISTENT_DOT) {
+        if (_animationState.value == ShowingPersistentDot) {
             // if we are currently showing a persistent dot, hide it and update the animationState
             notifyHidePersistentDot()
             if (scheduledEvent.value != null) {
-                animationState.value = ANIMATION_QUEUED
+                _animationState.value = AnimationQueued
             } else {
-                animationState.value = IDLE
+                _animationState.value = Idle
             }
-        } else if (animationState.value == ANIMATING_OUT) {
+        } else if (_animationState.value == AnimatingOut) {
             // if we are currently animating out, hide the dot. The animationState will be updated
             // once the animation has ended in the onAnimationEnd callback
             notifyHidePersistentDot()
@@ -206,9 +211,9 @@
             cancelCurrentlyDisplayedEvent()
             return
         }
-        if (animationState.value == IDLE) {
+        if (_animationState.value == Idle) {
             // If we are in IDLE state, set it to ANIMATION_QUEUED now
-            animationState.value = ANIMATION_QUEUED
+            _animationState.value = AnimationQueued
         }
     }
 
@@ -223,7 +228,7 @@
                 withTimeout(APPEAR_ANIMATION_DURATION) {
                     // wait for animationState to become RUNNING_CHIP_ANIM, then cancel the running
                     // animation job and run the disappear animation immediately
-                    animationState.first { it == RUNNING_CHIP_ANIM }
+                    _animationState.first { it == RunningChipAnim }
                     currentlyRunningAnimationJob?.cancel()
                     runChipDisappearAnimation()
                 }
@@ -241,7 +246,7 @@
 
         if (!event.showAnimation && event.forceVisible) {
             // If animations are turned off, we'll transition directly to the dot
-            animationState.value = SHOWING_PERSISTENT_DOT
+            _animationState.value = ShowingPersistentDot
             notifyTransitionToPersistentDot(event)
             return
         }
@@ -277,7 +282,7 @@
         if (hasPersistentDot) {
             statusBarWindowControllerStore.defaultDisplay.setForceStatusBarVisible(true)
         }
-        animationState.value = ANIMATING_IN
+        _animationState.value = AnimatingIn
 
         val animSet = collectStartAnimations()
         if (animSet.totalDuration > 500) {
@@ -289,7 +294,7 @@
         animSet.addListener(
             object : AnimatorListenerAdapter() {
                 override fun onAnimationEnd(animation: Animator) {
-                    animationState.value = RUNNING_CHIP_ANIM
+                    _animationState.value = RunningChipAnim
                 }
             }
         )
@@ -299,15 +304,15 @@
     private fun runChipDisappearAnimation() {
         Assert.isMainThread()
         val animSet2 = collectFinishAnimations()
-        animationState.value = ANIMATING_OUT
+        _animationState.value = AnimatingOut
         animSet2.addListener(
             object : AnimatorListenerAdapter() {
                 override fun onAnimationEnd(animation: Animator) {
-                    animationState.value =
+                    _animationState.value =
                         when {
-                            hasPersistentDot -> SHOWING_PERSISTENT_DOT
-                            scheduledEvent.value != null -> ANIMATION_QUEUED
-                            else -> IDLE
+                            hasPersistentDot -> ShowingPersistentDot
+                            scheduledEvent.value != null -> AnimationQueued
+                            else -> Idle
                         }
                     statusBarWindowControllerStore.defaultDisplay.setForceStatusBarVisible(false)
                 }
@@ -401,7 +406,7 @@
         pw.println("Scheduled event: ${scheduledEvent.value}")
         pw.println("Currently displayed event: $currentlyDisplayedEvent")
         pw.println("Has persistent privacy dot: $hasPersistentDot")
-        pw.println("Animation state: ${animationState.value}")
+        pw.println("Animation state: ${_animationState.value}")
         pw.println("Listeners:")
         if (listeners.isEmpty()) {
             pw.println("(none)")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLogger.kt
index 22b0b69..a1f7a9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLogger.kt
@@ -3,15 +3,14 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState
 import javax.inject.Inject
 
 /** Logs for the SystemStatusAnimationScheduler. */
 @SysUISingleton
 class SystemStatusAnimationSchedulerLogger
 @Inject
-constructor(
-    @SystemStatusAnimationSchedulerLog private val logBuffer: LogBuffer,
-) {
+constructor(@SystemStatusAnimationSchedulerLog private val logBuffer: LogBuffer) {
 
     fun logScheduleEvent(event: StatusEvent) {
         logBuffer.log(
@@ -23,11 +22,11 @@
                 bool1 = event.forceVisible
                 bool2 = event.showAnimation
             },
-            { "Scheduling event: $str1(forceVisible=$bool1, priority=$int1, showAnimation=$bool2)" }
+            { "Scheduling event: $str1(forceVisible=$bool1, priority=$int1, showAnimation=$bool2)" },
         )
     }
 
-    fun logUpdateEvent(event: StatusEvent, @SystemAnimationState animationState: Int) {
+    fun logUpdateEvent(event: StatusEvent, animationState: SystemEventAnimationState) {
         logBuffer.log(
             TAG,
             LogLevel.DEBUG,
@@ -36,12 +35,12 @@
                 int1 = event.priority
                 bool1 = event.forceVisible
                 bool2 = event.showAnimation
-                int2 = animationState
+                str2 = animationState.name
             },
             {
                 "Updating current event from: $str1(forceVisible=$bool1, priority=$int1, " +
-                    "showAnimation=$bool2), animationState=${animationState.name()}"
-            }
+                    "showAnimation=$bool2), animationState=$str2"
+            },
         )
     }
 
@@ -55,7 +54,7 @@
                 bool1 = event.forceVisible
                 bool2 = event.showAnimation
             },
-            { "Ignore event: $str1(forceVisible=$bool1, priority=$int1, showAnimation=$bool2)" }
+            { "Ignore event: $str1(forceVisible=$bool1, priority=$int1, showAnimation=$bool2)" },
         )
     }
 
@@ -67,26 +66,14 @@
         logBuffer.log(TAG, LogLevel.DEBUG, "Transition to persistent dot callback invoked")
     }
 
-    fun logAnimationStateUpdate(@SystemAnimationState animationState: Int) {
+    fun logAnimationStateUpdate(animationState: SystemEventAnimationState) {
         logBuffer.log(
             TAG,
             LogLevel.DEBUG,
-            { int1 = animationState },
-            { "AnimationState update: ${int1.name()}" }
+            { str1 = animationState.name },
+            { "AnimationState update: $str1" },
         )
-        animationState.name()
     }
-
-    private fun @receiver:SystemAnimationState Int.name() =
-        when (this) {
-            IDLE -> "IDLE"
-            ANIMATION_QUEUED -> "ANIMATION_QUEUED"
-            ANIMATING_IN -> "ANIMATING_IN"
-            RUNNING_CHIP_ANIM -> "RUNNING_CHIP_ANIM"
-            ANIMATING_OUT -> "ANIMATING_OUT"
-            SHOWING_PERSISTENT_DOT -> "SHOWING_PERSISTENT_DOT"
-            else -> "UNKNOWN_ANIMATION_STATE"
-        }
 }
 
 private const val TAG = "SystemStatusAnimationSchedulerLog"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/shared/model/SystemEventAnimationState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/shared/model/SystemEventAnimationState.kt
new file mode 100644
index 0000000..2446b81
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/shared/model/SystemEventAnimationState.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.events.shared.model
+
+/** Direct representation of the system event animation scheduler's current state */
+enum class SystemEventAnimationState {
+    /** No animation is in progress */
+    Idle,
+    /** An animation is queued, and awaiting the debounce period */
+    AnimationQueued,
+    /** System is animating out, and chip is animating in */
+    AnimatingIn,
+    /**
+     * Chip has animated in and is awaiting exit animation, and optionally playing its own animation
+     */
+    RunningChipAnim,
+    /** Chip is animating away and system is animating back */
+    AnimatingOut,
+    /** Chip has animated away, and the persistent dot is showing */
+    ShowingPersistentDot,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt
index 496fb83..1a521d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt
@@ -1,100 +1,141 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.systemui.statusbar.notification.collection.coordinator
 
 import android.util.Log
-
-import com.android.systemui.log.dagger.NotificationHeadsUpLog
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.NotificationHeadsUpLog
 import javax.inject.Inject
 
 private const val TAG = "HeadsUpCoordinator"
 
-class HeadsUpCoordinatorLogger constructor(
-    private val buffer: LogBuffer,
-    private val verbose: Boolean,
-) {
+class HeadsUpCoordinatorLogger(private val buffer: LogBuffer, private val verbose: Boolean) {
     @Inject
-    constructor(@NotificationHeadsUpLog buffer: LogBuffer) :
-            this(buffer, Log.isLoggable(TAG, Log.VERBOSE))
+    constructor(
+        @NotificationHeadsUpLog buffer: LogBuffer
+    ) : this(buffer, Log.isLoggable(TAG, Log.VERBOSE))
 
     fun logPostedEntryWillEvaluate(posted: HeadsUpCoordinator.PostedEntry, reason: String) {
         if (!verbose) return
-        buffer.log(TAG, LogLevel.VERBOSE, {
-            str1 = posted.key
-            str2 = reason
-            bool1 = posted.shouldHeadsUpEver
-            bool2 = posted.shouldHeadsUpAgain
-        }, {
-            "will evaluate posted entry $str1:" +
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                str1 = posted.key
+                str2 = reason
+                bool1 = posted.shouldHeadsUpEver
+                bool2 = posted.shouldHeadsUpAgain
+            },
+            {
+                "will evaluate posted entry $str1:" +
                     " reason=$str2 shouldHeadsUpEver=$bool1 shouldHeadsUpAgain=$bool2"
-        })
+            },
+        )
     }
 
     fun logPostedEntryWillNotEvaluate(posted: HeadsUpCoordinator.PostedEntry, reason: String) {
         if (!verbose) return
-        buffer.log(TAG, LogLevel.VERBOSE, {
-            str1 = posted.key
-            str2 = reason
-        }, {
-            "will not evaluate posted entry $str1: reason=$str2"
-        })
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                str1 = posted.key
+                str2 = reason
+            },
+            { "will not evaluate posted entry $str1: reason=$str2" },
+        )
     }
 
     fun logEvaluatingGroups(numGroups: Int) {
         if (!verbose) return
-        buffer.log(TAG, LogLevel.VERBOSE, {
-            int1 = numGroups
-        }, {
-            "evaluating groups for alert transfer: $int1"
-        })
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            { int1 = numGroups },
+            { "evaluating groups for alert transfer: $int1" },
+        )
     }
 
     fun logEvaluatingGroup(groupKey: String, numPostedEntries: Int, logicalGroupSize: Int) {
         if (!verbose) return
-        buffer.log(TAG, LogLevel.VERBOSE, {
-            str1 = groupKey
-            int1 = numPostedEntries
-            int2 = logicalGroupSize
-        }, {
-            "evaluating group for alert transfer: $str1" +
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                str1 = groupKey
+                int1 = numPostedEntries
+                int2 = logicalGroupSize
+            },
+            {
+                "evaluating group for alert transfer: $str1" +
                     " numPostedEntries=$int1 logicalGroupSize=$int2"
-        })
+            },
+        )
     }
 
     fun logEntryUpdatedByRanking(key: String, shouldHun: Boolean, reason: String) {
-        buffer.log(TAG, LogLevel.DEBUG, {
-            str1 = key
-            bool1 = shouldHun
-            str2 = reason
-        }, {
-            "updating entry via ranking applied: $str1 updated shouldHeadsUp=$bool1 because $str2"
-        })
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = key
+                bool1 = shouldHun
+                str2 = reason
+            },
+            {
+                "updating entry via ranking applied: $str1 updated shouldHeadsUp=$bool1 because $str2"
+            },
+        )
     }
 
     fun logEntryUpdatedToFullScreen(key: String, reason: String) {
-        buffer.log(TAG, LogLevel.DEBUG, {
-            str1 = key
-            str2 = reason
-        }, {
-            "updating entry to launch full screen intent: $str1 because $str2"
-        })
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = key
+                str2 = reason
+            },
+            { "updating entry to launch full screen intent: $str1 because $str2" },
+        )
     }
 
     fun logEntryDisqualifiedFromFullScreen(key: String, reason: String) {
-        buffer.log(TAG, LogLevel.DEBUG, {
-            str1 = key
-            str2 = reason
-        }, {
-            "updated entry no longer qualifies for full screen intent: $str1 because $str2"
-        })
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = key
+                str2 = reason
+            },
+            { "updated entry no longer qualifies for full screen intent: $str1 because $str2" },
+        )
     }
 
     fun logSummaryMarkedInterrupted(summaryKey: String, childKey: String) {
-        buffer.log(TAG, LogLevel.DEBUG, {
-            str1 = summaryKey
-            str2 = childKey
-        }, {
-            "marked group summary as interrupted: $str1 for alert transfer to child: $str2"
-        })
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = summaryKey
+                str2 = childKey
+            },
+            { "marked group summary as interrupted: $str1 for alert transfer to child: $str2" },
+        )
     }
 }
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 ec1dc0a7..87b16ef 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
@@ -1574,7 +1574,7 @@
         if (mMaxDisplayedNotifications != -1) {
             // The stack intrinsic height already contains the correct value when there is a limit
             // in the max number of notifications (e.g. as in keyguard).
-            height = mIntrinsicContentHeight;
+            height = mScrollViewFields.getIntrinsicStackHeight();
         } else {
             height = Math.max(0f, mAmbientState.getStackCutoff() - mAmbientState.getStackTop());
         }
@@ -2610,7 +2610,7 @@
     }
 
     @VisibleForTesting
-    void updateStackHeight() {
+    void updateIntrinsicStackHeight() {
         if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
 
         final int shelfIntrinsicHeight = mShelf != null ? mShelf.getIntrinsicHeight() : 0;
@@ -2621,8 +2621,11 @@
                 mMaxDisplayedNotifications,
                 shelfIntrinsicHeight
         );
-        mIntrinsicContentHeight = notificationsHeight;
-        final int fullStackHeight = notificationsHeight + footerIntrinsicHeight + mBottomPadding;
+        // 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);
             notifyStackHeightChangedListeners();
@@ -2631,7 +2634,7 @@
 
     private void updateContentHeight() {
         if (SceneContainerFlag.isEnabled()) {
-            updateStackHeight();
+            updateIntrinsicStackHeight();
             return;
         }
 
@@ -5348,7 +5351,12 @@
     public void setMaxDisplayedNotifications(int maxDisplayedNotifications) {
         if (mMaxDisplayedNotifications != maxDisplayedNotifications) {
             mMaxDisplayedNotifications = maxDisplayedNotifications;
-            updateContentHeight();
+            if (SceneContainerFlag.isEnabled()) {
+                updateIntrinsicStackHeight();
+                updateStackEndHeightAndStackHeight(mAmbientState.getExpansionFraction());
+            } else {
+                updateContentHeight();
+            }
             notifyHeightChangeListener(mShelf);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
index 5d37476..6042964 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
@@ -18,7 +18,7 @@
 package com.android.systemui.statusbar.notification.stack.domain.interactor
 
 import android.content.Context
-import com.android.systemui.common.ui.data.repository.ConfigurationRepository
+import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
@@ -29,6 +29,8 @@
 import com.android.systemui.statusbar.policy.SplitShadeStateController
 import dagger.Lazy
 import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.FlowPreview
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
@@ -36,17 +38,17 @@
 import kotlinx.coroutines.flow.debounce
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onStart
 
 /** Encapsulates business-logic specifically related to the shared notification stack container. */
+@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
 @SysUISingleton
 class SharedNotificationContainerInteractor
 @Inject
 constructor(
-    configurationRepository: ConfigurationRepository,
     private val context: Context,
     private val splitShadeStateController: Lazy<SplitShadeStateController>,
     private val shadeInteractor: Lazy<ShadeInteractor>,
+    configurationInteractor: ConfigurationInteractor,
     keyguardInteractor: KeyguardInteractor,
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
     largeScreenHeaderHelperLazy: Lazy<LargeScreenHeaderHelper>,
@@ -59,9 +61,6 @@
     /** An internal modification was made to notifications */
     val notificationStackChanged = _notificationStackChanged.debounce(20L)
 
-    private val configurationChangeEvents =
-        configurationRepository.onAnyConfigurationChange.onStart { emit(Unit) }
-
     /* Warning: Even though the value it emits only contains the split shade status, this flow must
      * emit a value whenever the configuration *or* the split shade status changes. Adding a
      * distinctUntilChanged() to this would cause configurationBasedDimensions to miss configuration
@@ -69,13 +68,14 @@
      */
     private val dimensionsUpdateEventsWithShouldUseSplitShade: Flow<Boolean> =
         if (SceneContainerFlag.isEnabled) {
-            combine(configurationChangeEvents, shadeInteractor.get().isShadeLayoutWide) {
-                _,
-                isShadeLayoutWide ->
+            combine(
+                configurationInteractor.onAnyConfigurationChange,
+                shadeInteractor.get().isShadeLayoutWide,
+            ) { _, isShadeLayoutWide ->
                 isShadeLayoutWide
             }
         } else {
-            configurationChangeEvents.map {
+            configurationInteractor.onAnyConfigurationChange.map {
                 splitShadeStateController.get().shouldUseSplitNotificationShade(context.resources)
             }
         }
@@ -115,11 +115,6 @@
             isUdfpsSupported || !ambientIndicationVisible
         }
 
-    val isSplitShadeEnabled: Flow<Boolean> =
-        configurationBasedDimensions
-            .map { dimens: ConfigurationBasedDimensions -> dimens.useSplitShade }
-            .distinctUntilChanged()
-
     /** Top position (without translation) of the shared container. */
     fun setTopPosition(top: Float) {
         _topPosition.value = top
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
index 574ca3f..56b3356 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
@@ -104,7 +104,7 @@
             1f
         } else if (
             change.isTransitioningBetween(Scenes.Gone, Scenes.Shade) ||
-                change.isTransitioning(from = Scenes.Gone, to = Scenes.Lockscreen)
+                change.isTransitioning(from = Scenes.Shade, to = Scenes.Lockscreen)
         ) {
             shadeExpansion
         } else if (change.isTransitioningBetween(Scenes.Gone, Scenes.QuickSettings)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 878ae91..9515029 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -484,19 +484,28 @@
     }
 
     fun keyguardAlpha(viewState: ViewStateAccessor, scope: CoroutineScope): Flow<Float> {
+        val isKeyguardOccluded =
+            keyguardTransitionInteractor.transitionValue(OCCLUDED).map { it == 1f }
+
+        val isKeyguardNotVisibleInState =
+            if (SceneContainerFlag.isEnabled) {
+                isKeyguardOccluded
+            } else {
+                anyOf(
+                    isKeyguardOccluded,
+                    keyguardTransitionInteractor
+                        .transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+                        .map { it == 1f },
+                )
+            }
+
         // Transitions are not (yet) authoritative for NSSL; they still rely on StatusBarState to
         // help determine when the device has fully moved to GONE or OCCLUDED state. Once SHADE
         // state has been set, let shade alpha take over
         val isKeyguardNotVisible =
-            combine(
-                anyOf(
-                    keyguardTransitionInteractor.transitionValue(OCCLUDED).map { it == 1f },
-                    keyguardTransitionInteractor
-                        .transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
-                        .map { it == 1f },
-                ),
-                keyguardInteractor.statusBarState,
-            ) { isKeyguardNotVisibleInState, statusBarState ->
+            combine(isKeyguardNotVisibleInState, keyguardInteractor.statusBarState) {
+                isKeyguardNotVisibleInState,
+                statusBarState ->
                 isKeyguardNotVisibleInState && statusBarState == SHADE
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index cd59d4e..be2fb68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -58,6 +58,7 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore;
 import com.android.systemui.statusbar.disableflags.DisableStateTracker;
 import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
@@ -300,7 +301,7 @@
             KeyguardStatusBarViewModel keyguardStatusBarViewModel,
             BiometricUnlockController biometricUnlockController,
             SysuiStatusBarStateController statusBarStateController,
-            StatusBarContentInsetsProvider statusBarContentInsetsProvider,
+            StatusBarContentInsetsProviderStore statusBarContentInsetsProviderStore,
             UserManager userManager,
             StatusBarUserChipViewModel userChipViewModel,
             SecureSettings secureSettings,
@@ -327,7 +328,7 @@
         mKeyguardStatusBarViewModel = keyguardStatusBarViewModel;
         mBiometricUnlockController = biometricUnlockController;
         mStatusBarStateController = statusBarStateController;
-        mInsetsProvider = statusBarContentInsetsProvider;
+        mInsetsProvider = statusBarContentInsetsProviderStore.getDefaultDisplay();
         mUserManager = userManager;
         mStatusBarUserChipViewModel = userChipViewModel;
         mSecureSettings = secureSettings;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index ff7c143..746d6a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -38,6 +38,7 @@
 import com.android.systemui.shade.ShadeViewController
 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
 import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator
+import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore
 import com.android.systemui.statusbar.policy.Clock
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.window.StatusBarWindowStateController
@@ -333,7 +334,7 @@
         private val configurationController: ConfigurationController,
         private val statusOverlayHoverListenerFactory: StatusOverlayHoverListenerFactory,
         private val darkIconDispatcher: DarkIconDispatcher,
-        private val statusBarContentInsetsProvider: StatusBarContentInsetsProvider,
+        private val statusBarContentInsetsProviderStore: StatusBarContentInsetsProviderStore,
     ) {
         fun create(view: PhoneStatusBarView): PhoneStatusBarViewController {
             val statusBarMoveFromCenterAnimationController =
@@ -359,7 +360,7 @@
                 configurationController,
                 statusOverlayHoverListenerFactory,
                 darkIconDispatcher,
-                statusBarContentInsetsProvider,
+                statusBarContentInsetsProviderStore.defaultDisplay,
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
index c6f6bd9..d991b1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
@@ -24,6 +24,7 @@
 import android.graphics.Rect
 import android.util.LruCache
 import android.util.Pair
+import android.view.Display.DEFAULT_DISPLAY
 import android.view.DisplayCutout
 import android.view.Surface
 import androidx.annotation.VisibleForTesting
@@ -37,7 +38,7 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.commandline.CommandRegistry
-import com.android.systemui.statusbar.phone.StatusBarContentInsetsProviderImpl.CacheKey
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
 import com.android.systemui.statusbar.policy.CallbackController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE
@@ -70,6 +71,17 @@
     CallbackController<StatusBarContentInsetsChangedListener> {
 
     /**
+     * Called when the [StatusBarContentInsetsProvider] should start doing its work and allocate its
+     * resources.
+     */
+    fun start()
+
+    /**
+     * Called when the [StatusBarContentInsetsProvider] should stop and do any required clean up.
+     */
+    fun stop()
+
+    /**
      * Some views may need to care about whether or not the current top display cutout is located in
      * the corner rather than somewhere in the center. In the case of a corner cutout, the status
      * bar area is contiguous.
@@ -157,10 +169,15 @@
             context.resources.getBoolean(R.bool.config_enablePrivacyDot)
         }
 
-    init {
+    private val nameSuffix =
+        if (context.displayId == DEFAULT_DISPLAY) "" else context.displayId.toString()
+    private val dumpableName = TAG + nameSuffix
+    private val commandName = StatusBarInsetsCommand.NAME + nameSuffix
+
+    override fun start() {
         configurationController.addCallback(this)
-        dumpManager.registerDumpable(TAG, this)
-        commandRegistry.registerCommand(StatusBarInsetsCommand.NAME) {
+        dumpManager.registerDumpable(dumpableName, this)
+        commandRegistry.registerCommand(commandName) {
             StatusBarInsetsCommand(
                 object : StatusBarInsetsCommand.Callback {
                     override fun onExecute(
@@ -174,6 +191,13 @@
         }
     }
 
+    override fun stop() {
+        StatusBarConnectedDisplays.assertInNewMode()
+        configurationController.removeCallback(this)
+        dumpManager.unregisterDumpable(dumpableName)
+        commandRegistry.unregisterCommand(commandName)
+    }
+
     override fun addCallback(listener: StatusBarContentInsetsChangedListener) {
         listeners.add(listener)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index f7fea7b..92b609e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -56,6 +56,7 @@
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Flags;
+import com.android.systemui.animation.back.FlingOnBackAnimationCallback;
 import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor;
@@ -236,9 +237,10 @@
             }
     };
 
-    private final OnBackAnimationCallback mOnBackInvokedCallback = new OnBackAnimationCallback() {
+    private final OnBackAnimationCallback mOnBackInvokedCallback =
+            new FlingOnBackAnimationCallback() {
         @Override
-        public void onBackInvoked() {
+        public void onBackInvokedCompat() {
             if (DEBUG) {
                 Log.d(TAG, "onBackInvokedCallback() called, invoking onBackPressed()");
             }
@@ -249,21 +251,21 @@
         }
 
         @Override
-        public void onBackProgressed(BackEvent event) {
+        public void onBackProgressedCompat(@NonNull BackEvent event) {
             if (shouldPlayBackAnimation() && mPrimaryBouncerView.getDelegate() != null) {
                 mPrimaryBouncerView.getDelegate().getBackCallback().onBackProgressed(event);
             }
         }
 
         @Override
-        public void onBackCancelled() {
+        public void onBackCancelledCompat() {
             if (shouldPlayBackAnimation() && mPrimaryBouncerView.getDelegate() != null) {
                 mPrimaryBouncerView.getDelegate().getBackCallback().onBackCancelled();
             }
         }
 
         @Override
-        public void onBackStarted(BackEvent event) {
+        public void onBackStartedCompat(@NonNull BackEvent event) {
             if (shouldPlayBackAnimation() && mPrimaryBouncerView.getDelegate() != null) {
                 mPrimaryBouncerView.getDelegate().getBackCallback().onBackStarted(event);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.kt
index ae0e76f..584cd3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.fragments.FragmentHostManager
 import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import java.util.Optional
 
 /** Encapsulates all logic for the status bar window state management. */
@@ -82,6 +83,7 @@
             context: Context,
             viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager,
             statusBarConfigurationController: StatusBarConfigurationController,
+            contentInsetsProvider: StatusBarContentInsetsProvider,
         ): StatusBarWindowController
     }
 }
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 e4c6737..6953bbf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
@@ -99,7 +99,7 @@
             @Assisted ViewCaptureAwareWindowManager viewCaptureAwareWindowManager,
             @Assisted StatusBarConfigurationController statusBarConfigurationController,
             IWindowManager iWindowManager,
-            StatusBarContentInsetsProvider contentInsetsProvider,
+            @Assisted StatusBarContentInsetsProvider contentInsetsProvider,
             FragmentService fragmentService,
             Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider) {
         mContext = context;
@@ -370,7 +370,8 @@
         StatusBarWindowControllerImpl create(
                 @NonNull Context context,
                 @NonNull ViewCaptureAwareWindowManager viewCaptureAwareWindowManager,
-                @NonNull StatusBarConfigurationController statusBarConfigurationController);
+                @NonNull StatusBarConfigurationController statusBarConfigurationController,
+                @NonNull StatusBarContentInsetsProvider contentInsetsProvider);
     }
 
 }
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 d83a237..051d463 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.display.data.repository.SingleDisplayStore
 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
 import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore
+import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 
@@ -43,6 +44,7 @@
     private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
     private val viewCaptureAwareWindowManagerFactory: ViewCaptureAwareWindowManager.Factory,
     private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
+    private val statusBarContentInsetsProviderStore: StatusBarContentInsetsProviderStore,
     displayRepository: DisplayRepository,
 ) :
     StatusBarWindowControllerStore,
@@ -64,6 +66,7 @@
             statusBarDisplayContext.context,
             viewCaptureAwareWindowManager,
             statusBarConfigurationControllerStore.forDisplay(displayId),
+            statusBarContentInsetsProviderStore.forDisplay(displayId),
         )
     }
 
@@ -78,6 +81,7 @@
     viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager,
     factory: StatusBarWindowControllerImpl.Factory,
     statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
+    statusBarContentInsetsProviderStore: StatusBarContentInsetsProviderStore,
 ) :
     StatusBarWindowControllerStore,
     PerDisplayStore<StatusBarWindowController> by SingleDisplayStore(
@@ -85,6 +89,7 @@
             context,
             viewCaptureAwareWindowManager,
             statusBarConfigurationControllerStore.defaultDisplay,
+            statusBarContentInsetsProviderStore.defaultDisplay,
         )
     ) {
 
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 618722a..be740ed 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
@@ -44,19 +44,15 @@
                     titleSuccessResId = R.string.touchpad_back_gesture_success_title,
                     bodySuccessResId = R.string.touchpad_back_gesture_success_body,
                 ),
-            animations =
-                TutorialScreenConfig.Animations(
-                    educationResId = R.raw.trackpad_back_edu,
-                    successResId = R.raw.trackpad_back_success,
-                ),
+            animations = TutorialScreenConfig.Animations(educationResId = R.raw.trackpad_back_edu),
         )
     val recognizer = rememberBackGestureRecognizer(LocalContext.current.resources)
     val gestureUiState: Flow<GestureUiState> =
         remember(recognizer) {
             GestureFlowAdapter(recognizer).gestureStateAsFlow.map {
                 it.toGestureUiState(
-                    progressStartMark = "",
-                    progressEndMark = "",
+                    progressStartMarker = "",
+                    progressEndMarker = "",
                     successAnimation = R.raw.trackpad_back_success,
                 )
             }
@@ -67,9 +63,7 @@
 @Composable
 private fun rememberBackGestureRecognizer(resources: Resources): GestureRecognizer {
     val distance =
-        resources.getDimensionPixelSize(
-            com.android.internal.R.dimen.system_gestures_distance_threshold
-        )
+        resources.getDimensionPixelSize(R.dimen.touchpad_tutorial_gestures_distance_threshold)
     return remember(distance) { BackGestureRecognizer(distance) }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt
index 11e1ff4..2332c00 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt
@@ -51,20 +51,20 @@
 
     data class InProgress(
         val progress: Float = 0f,
-        val progressStartMark: String = "",
-        val progressEndMark: String = "",
+        val progressStartMarker: String,
+        val progressEndMarker: String,
     ) : GestureUiState
 }
 
 fun GestureState.toGestureUiState(
-    progressStartMark: String,
-    progressEndMark: String,
+    progressStartMarker: String,
+    progressEndMarker: String,
     successAnimation: Int,
 ): GestureUiState {
     return when (this) {
         GestureState.NotStarted -> NotStarted
         is GestureState.InProgress ->
-            GestureUiState.InProgress(this.progress, progressStartMark, progressEndMark)
+            GestureUiState.InProgress(this.progress, progressStartMarker, progressEndMarker)
         is GestureState.Finished -> GestureUiState.Finished(successAnimation)
     }
 }
@@ -72,9 +72,13 @@
 fun GestureUiState.toTutorialActionState(): TutorialActionState {
     return when (this) {
         NotStarted -> TutorialActionState.NotStarted
-        // progress is disabled for now as views are not ready to handle varying progress
-        is GestureUiState.InProgress -> TutorialActionState.InProgress(progress = 0f)
-        is Finished -> TutorialActionState.Finished
+        is GestureUiState.InProgress ->
+            TutorialActionState.InProgress(
+                progress = progress,
+                startMarker = progressStartMarker,
+                endMarker = progressEndMarker,
+            )
+        is Finished -> TutorialActionState.Finished(successAnimation)
     }
 }
 
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 05871ce..1d5ee77 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
@@ -43,19 +43,15 @@
                     titleSuccessResId = R.string.touchpad_home_gesture_success_title,
                     bodySuccessResId = R.string.touchpad_home_gesture_success_body,
                 ),
-            animations =
-                TutorialScreenConfig.Animations(
-                    educationResId = R.raw.trackpad_home_edu,
-                    successResId = R.raw.trackpad_home_success,
-                ),
+            animations = TutorialScreenConfig.Animations(educationResId = R.raw.trackpad_home_edu),
         )
     val recognizer = rememberHomeGestureRecognizer(LocalContext.current.resources)
     val gestureUiState: Flow<GestureUiState> =
         remember(recognizer) {
             GestureFlowAdapter(recognizer).gestureStateAsFlow.map {
                 it.toGestureUiState(
-                    progressStartMark = "",
-                    progressEndMark = "",
+                    progressStartMarker = "",
+                    progressEndMarker = "",
                     successAnimation = R.raw.trackpad_home_success,
                 )
             }
@@ -66,9 +62,7 @@
 @Composable
 private fun rememberHomeGestureRecognizer(resources: Resources): GestureRecognizer {
     val distance =
-        resources.getDimensionPixelSize(
-            com.android.internal.R.dimen.system_gestures_distance_threshold
-        )
+        resources.getDimensionPixelSize(R.dimen.touchpad_tutorial_gestures_distance_threshold)
     return remember(distance) { HomeGestureRecognizer(distance) }
 }
 
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 4fd1644..4dc38c2 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
@@ -44,18 +44,15 @@
                     bodySuccessResId = R.string.touchpad_recent_apps_gesture_success_body,
                 ),
             animations =
-                TutorialScreenConfig.Animations(
-                    educationResId = R.raw.trackpad_recent_apps_edu,
-                    successResId = R.raw.trackpad_recent_apps_success,
-                ),
+                TutorialScreenConfig.Animations(educationResId = R.raw.trackpad_recent_apps_edu),
         )
     val recognizer = rememberRecentAppsGestureRecognizer(LocalContext.current.resources)
     val gestureUiState: Flow<GestureUiState> =
         remember(recognizer) {
             GestureFlowAdapter(recognizer).gestureStateAsFlow.map {
                 it.toGestureUiState(
-                    progressStartMark = "",
-                    progressEndMark = "",
+                    progressStartMarker = "",
+                    progressEndMarker = "",
                     successAnimation = R.raw.trackpad_recent_apps_success,
                 )
             }
@@ -66,9 +63,7 @@
 @Composable
 private fun rememberRecentAppsGestureRecognizer(resources: Resources): GestureRecognizer {
     val distance =
-        resources.getDimensionPixelSize(
-            com.android.internal.R.dimen.system_gestures_distance_threshold
-        )
+        resources.getDimensionPixelSize(R.dimen.touchpad_tutorial_gestures_distance_threshold)
     val velocity = resources.getDimension(R.dimen.touchpad_recent_apps_gesture_velocity_threshold)
     return remember(distance, velocity) { RecentAppsGestureRecognizer(distance, velocity) }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizer.kt
index 024048c..35ea0ea 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizer.kt
@@ -18,6 +18,9 @@
 
 import android.util.MathUtils
 import android.view.MotionEvent
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection.LEFT
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection.RIGHT
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
 import kotlin.math.abs
 
 /**
@@ -44,7 +47,13 @@
             gestureStateChangedCallback,
             gestureState,
             isFinished = { abs(it.deltaX) >= gestureDistanceThresholdPx },
-            progress = { MathUtils.saturate(abs(it.deltaX / gestureDistanceThresholdPx)) },
+            progress = ::getProgress,
         )
     }
+
+    private fun getProgress(it: Moving): InProgress {
+        val direction = if (it.deltaX > 0) RIGHT else LEFT
+        val value = MathUtils.saturate(abs(it.deltaX / gestureDistanceThresholdPx))
+        return InProgress(value, direction)
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureState.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureState.kt
index b513c49..f27ddb5 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureState.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureState.kt
@@ -21,5 +21,11 @@
 
     data object Finished : GestureState
 
-    data class InProgress(val progress: Float = 0f) : GestureState
+    data class InProgress(val progress: Float = 0f, val direction: GestureDirection? = null) :
+        GestureState
+}
+
+enum class GestureDirection {
+    LEFT,
+    RIGHT,
 }
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureStateUpdates.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureStateUpdates.kt
index f194677..24f5d1f 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureStateUpdates.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureStateUpdates.kt
@@ -21,7 +21,7 @@
     gestureStateChangedCallback: (GestureState) -> Unit,
     gestureState: DistanceGestureState?,
     isFinished: (Finished) -> Boolean,
-    progress: (Moving) -> Float,
+    progress: (Moving) -> GestureState.InProgress,
 ) {
     when (gestureState) {
         is Finished -> {
@@ -32,7 +32,7 @@
             }
         }
         is Moving -> {
-            gestureStateChangedCallback(GestureState.InProgress(progress(gestureState)))
+            gestureStateChangedCallback(progress(gestureState))
         }
         is Started -> gestureStateChangedCallback(GestureState.InProgress())
         else -> {}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt
index b804b9a..e10b825 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt
@@ -18,6 +18,7 @@
 
 import android.util.MathUtils
 import android.view.MotionEvent
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
 
 /** Recognizes touchpad home gesture, that is - using three fingers on touchpad - swiping up. */
 class HomeGestureRecognizer(private val gestureDistanceThresholdPx: Int) : GestureRecognizer {
@@ -40,7 +41,7 @@
             gestureStateChangedCallback,
             gestureState,
             isFinished = { -it.deltaY >= gestureDistanceThresholdPx },
-            progress = { MathUtils.saturate(-it.deltaY / gestureDistanceThresholdPx) },
+            progress = { InProgress(MathUtils.saturate(-it.deltaY / gestureDistanceThresholdPx)) },
         )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt
index 7d484ee..c478886 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt
@@ -54,7 +54,9 @@
                 -state.deltaY >= gestureDistanceThresholdPx &&
                     abs(velocityTracker.calculateVelocity().value) <= velocityThresholdPxPerMs
             },
-            progress = { MathUtils.saturate(-it.deltaY / gestureDistanceThresholdPx) },
+            progress = {
+                GestureState.InProgress(MathUtils.saturate(-it.deltaY / gestureDistanceThresholdPx))
+            },
         )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 3d2ebf2..07509e6 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -64,6 +64,8 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.LayerDrawable;
 import android.graphics.drawable.RotateDrawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.RoundRectShape;
 import android.media.AudioManager;
 import android.media.AudioSystem;
 import android.os.Debug;
@@ -115,6 +117,7 @@
 import com.android.internal.view.RotationPolicy;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dumpable;
+import com.android.systemui.Flags;
 import com.android.systemui.Prefs;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.haptics.slider.HapticSliderViewBinder;
@@ -656,6 +659,11 @@
             mRingerIcon = mRinger.findViewById(R.id.ringer_icon);
         }
 
+        if (Flags.hideRingerButtonInSingleVolumeMode() && AudioSystem.isSingleVolume(mContext)) {
+            mRingerAndDrawerContainer.setVisibility(INVISIBLE);
+            mRinger.setVisibility(INVISIBLE);
+        }
+
         mSelectedRingerIcon = mDialog.findViewById(R.id.volume_new_ringer_active_icon);
         mSelectedRingerContainer = mDialog.findViewById(
                 R.id.volume_new_ringer_active_icon_container);
@@ -2341,10 +2349,31 @@
             return;
         }
 
-        final ColorDrawable solidDrawable = new ColorDrawable(
+        LayerDrawable background;
+        // mRingerAndDrawerContainer has rounded corner.
+        // But when it's not visible, mTopContainer needs to have rounded corner.
+        if (Flags.hideRingerButtonInSingleVolumeMode()
+                && mRingerAndDrawerContainer.getVisibility() != VISIBLE
+        ) {
+            float[] radius = new float[] {
+                mDialogCornerRadius, mDialogCornerRadius,  // Top-left corner
+                mDialogCornerRadius, mDialogCornerRadius,  // Top-right corner
+                0, 0,  // Bottom-right corner
+                0, 0   // Bottom-left corner
+            };
+
+            ShapeDrawable roundedDrawable = new ShapeDrawable(
+                    new RoundRectShape(radius, null, null));
+            roundedDrawable.getPaint().setColor(Utils.getColorAttrDefaultColor(
+                    mContext, com.android.internal.R.attr.colorSurface));
+
+            background = new LayerDrawable(new Drawable[] { roundedDrawable });
+        } else {
+            final ColorDrawable solidDrawable = new ColorDrawable(
                 Utils.getColorAttrDefaultColor(mContext, com.android.internal.R.attr.colorSurface));
 
-        final LayerDrawable background = new LayerDrawable(new Drawable[] { solidDrawable });
+            background = new LayerDrawable(new Drawable[] { solidDrawable });
+        }
 
         // Size the solid color to match the primary volume row. In landscape, extend it upwards
         // slightly so that it fills in the bottom corners of the ringer icon, whose background is
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 4eae3b9a..c7f5801 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
@@ -17,8 +17,11 @@
 package com.android.systemui.volume.dialog.ui.utils
 
 import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ValueAnimator
 import android.view.ViewPropertyAnimator
 import kotlin.coroutines.resume
+import kotlinx.coroutines.CancellableContinuation
 import kotlinx.coroutines.suspendCancellableCoroutine
 
 /**
@@ -39,11 +42,12 @@
             }
 
             override fun onAnimationEnd(animation: Animator) {
-                continuation.resume(Unit)
+                continuation.resumeIfCan(Unit)
                 animationListener?.onAnimationEnd(animation)
             }
 
             override fun onAnimationCancel(animation: Animator) {
+                continuation.resumeIfCan(Unit)
                 animationListener?.onAnimationCancel(animation)
             }
 
@@ -54,3 +58,30 @@
     )
     continuation.invokeOnCancellation { this.cancel() }
 }
+
+/**
+ * Starts animation and suspends until it's finished. Cancels the animation if the running coroutine
+ * is cancelled.
+ */
+@Suppress("UNCHECKED_CAST")
+suspend fun <T> ValueAnimator.awaitAnimation(onValueChanged: (T) -> Unit) {
+    suspendCancellableCoroutine { continuation ->
+        addListener(
+            object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) = continuation.resumeIfCan(Unit)
+
+                override fun onAnimationCancel(animation: Animator) = continuation.resumeIfCan(Unit)
+            }
+        )
+        addUpdateListener { onValueChanged(it.animatedValue as T) }
+
+        start()
+        continuation.invokeOnCancellation { cancel() }
+    }
+}
+
+private fun <T> CancellableContinuation<T>.resumeIfCan(value: T) {
+    if (!isCancelled && !isCompleted) {
+        resume(value)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 7889b3c..61eeab3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -65,7 +65,6 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.VibratorHelper
-import com.android.systemui.statusbar.events.ANIMATING_OUT
 import com.android.systemui.testKosmos
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
 import com.android.systemui.util.concurrency.FakeExecutor
@@ -176,7 +175,7 @@
             BiometricStatusInteractorImpl(
                 activityTaskManager,
                 biometricStatusRepository,
-                fingerprintRepository
+                fingerprintRepository,
             )
         iconProvider = IconProvider(context)
         // Set up default logo icon
@@ -245,7 +244,7 @@
     @Test
     fun testIgnoresAnimatedInWhenDialogAnimatingOut() {
         val container = initializeFingerprintContainer(addToView = false)
-        container.mContainerState = ANIMATING_OUT
+        container.mContainerState = 4 // STATE_ANIMATING_OUT
         container.addToView()
         waitForIdleSync()
 
@@ -278,7 +277,7 @@
             .onDismissed(
                 eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
                 eq<ByteArray?>(null), /* credentialAttestation */
-                eq(authContainer?.requestId ?: 0L)
+                eq(authContainer?.requestId ?: 0L),
             )
         assertThat(container.parent).isNull()
     }
@@ -292,13 +291,13 @@
         verify(callback)
             .onSystemEvent(
                 eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL),
-                eq(authContainer?.requestId ?: 0L)
+                eq(authContainer?.requestId ?: 0L),
             )
         verify(callback)
             .onDismissed(
                 eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
                 eq<ByteArray?>(null), /* credentialAttestation */
-                eq(authContainer?.requestId ?: 0L)
+                eq(authContainer?.requestId ?: 0L),
             )
         assertThat(container.parent).isNull()
     }
@@ -313,7 +312,7 @@
             .onDismissed(
                 eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
                 eq<ByteArray?>(null), /* credentialAttestation */
-                eq(authContainer?.requestId ?: 0L)
+                eq(authContainer?.requestId ?: 0L),
             )
         assertThat(container.parent).isNull()
     }
@@ -340,7 +339,7 @@
             .onDismissed(
                 eq(AuthDialogCallback.DISMISSED_ERROR),
                 eq<ByteArray?>(null), /* credentialAttestation */
-                eq(authContainer?.requestId ?: 0L)
+                eq(authContainer?.requestId ?: 0L),
             )
         assertThat(authContainer!!.parent).isNull()
     }
@@ -454,7 +453,7 @@
         val container =
             initializeFingerprintContainer(
                 authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
-                verticalListContentView = PromptVerticalListContentView.Builder().build()
+                verticalListContentView = PromptVerticalListContentView.Builder().build(),
             )
         // Two-step credential view should show -
         // 1. biometric prompt without sensor 2. credential view ui
@@ -479,7 +478,7 @@
         val container =
             initializeFingerprintContainer(
                 authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
-                contentViewWithMoreOptionsButton = contentView
+                contentViewWithMoreOptionsButton = contentView,
             )
         waitForIdleSync()
 
@@ -565,7 +564,7 @@
     }
 
     private fun initializeCredentialPasswordContainer(
-        addToView: Boolean = true,
+        addToView: Boolean = true
     ): TestAuthContainerView {
         whenever(userManager.getCredentialOwnerProfile(anyInt())).thenReturn(20)
         whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(20)))
@@ -597,25 +596,25 @@
                 fingerprintProps = fingerprintSensorPropertiesInternal(),
                 verticalListContentView = verticalListContentView,
             ),
-            addToView
+            addToView,
         )
 
     private fun initializeCoexContainer(
         authenticators: Int = BiometricManager.Authenticators.BIOMETRIC_WEAK,
-        addToView: Boolean = true
+        addToView: Boolean = true,
     ) =
         initializeContainer(
             TestAuthContainerView(
                 authenticators = authenticators,
                 fingerprintProps = fingerprintSensorPropertiesInternal(),
-                faceProps = faceSensorPropertiesInternal()
+                faceProps = faceSensorPropertiesInternal(),
             ),
-            addToView
+            addToView,
         )
 
     private fun initializeContainer(
         view: TestAuthContainerView,
-        addToView: Boolean
+        addToView: Boolean,
     ): TestAuthContainerView {
         authContainer = view
 
@@ -668,7 +667,7 @@
                 biometricStatusInteractor,
                 udfpsUtils,
                 iconProvider,
-                activityTaskManager
+                activityTaskManager,
             ),
             { credentialViewModel },
             fakeExecutor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt
index fc2ad60..eae8285 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt
@@ -53,7 +53,7 @@
 import com.android.systemui.shade.ShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
 import com.android.systemui.shade.carrier.ShadeCarrierGroup
 import com.android.systemui.shade.carrier.ShadeCarrierGroupController
-import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import com.android.systemui.statusbar.data.repository.fakeStatusBarContentInsetsProviderStore
 import com.android.systemui.statusbar.phone.StatusIconContainer
 import com.android.systemui.statusbar.phone.StatusOverlayHoverListenerFactory
 import com.android.systemui.statusbar.phone.ui.StatusBarIconController
@@ -63,6 +63,7 @@
 import com.android.systemui.statusbar.policy.NextAlarmController
 import com.android.systemui.statusbar.policy.VariableDateView
 import com.android.systemui.statusbar.policy.VariableDateViewController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.capture
@@ -93,6 +94,10 @@
 @RunWith(AndroidTestingRunner::class)
 class ShadeHeaderControllerTest : SysuiTestCase() {
 
+    private val kosmos = testKosmos()
+    private val insetsProviderStore = kosmos.fakeStatusBarContentInsetsProviderStore
+    private val insetsProvider = insetsProviderStore.defaultDisplay
+
     @Mock(answer = Answers.RETURNS_MOCKS) private lateinit var view: MotionLayout
     @Mock private lateinit var statusIcons: StatusIconContainer
     @Mock private lateinit var statusBarIconController: StatusBarIconController
@@ -107,7 +112,6 @@
     @Mock private lateinit var batteryMeterView: BatteryMeterView
     @Mock private lateinit var batteryMeterViewController: BatteryMeterViewController
     @Mock private lateinit var privacyIconsController: HeaderPrivacyIconsController
-    @Mock private lateinit var insetsProvider: StatusBarContentInsetsProvider
     @Mock private lateinit var variableDateViewControllerFactory: VariableDateViewController.Factory
     @Mock private lateinit var variableDateViewController: VariableDateViewController
     @Mock private lateinit var dumpManager: DumpManager
@@ -190,7 +194,7 @@
                 statusBarIconController,
                 iconManagerFactory,
                 privacyIconsController,
-                insetsProvider,
+                insetsProviderStore,
                 configurationController,
                 variableDateViewControllerFactory,
                 batteryMeterViewController,
@@ -201,7 +205,7 @@
                 qsBatteryModeController,
                 nextAlarmController,
                 activityStarter,
-                mStatusOverlayHoverListenerFactory
+                mStatusOverlayHoverListenerFactory,
             )
         whenever(view.isAttachedToWindow).thenReturn(true)
         shadeHeaderController.init()
@@ -597,7 +601,7 @@
                     anyInt(),
                     anyInt(),
                     anyInt(),
-                    anyInt()
+                    anyInt(),
                 )
             )
             .thenReturn(mockConstraintsChanges)
@@ -631,7 +635,7 @@
                     anyInt(),
                     anyInt(),
                     anyInt(),
-                    anyInt()
+                    anyInt(),
                 )
             )
             .thenReturn(mockConstraintsChanges)
@@ -751,7 +755,7 @@
         whenever(
                 combinedShadeHeadersConstraintManager.centerCutoutConstraints(
                     Mockito.anyBoolean(),
-                    anyInt()
+                    anyInt(),
                 )
             )
             .thenReturn(mockConstraintsChanges)
@@ -788,7 +792,7 @@
         whenever(
                 combinedShadeHeadersConstraintManager.centerCutoutConstraints(
                     Mockito.anyBoolean(),
-                    anyInt()
+                    anyInt(),
                 )
             )
             .thenReturn(mockConstraintsChanges)
@@ -899,7 +903,7 @@
         top: Int,
         right: Int,
         bottom: Int,
-        listener: View.OnLayoutChangeListener
+        listener: View.OnLayoutChangeListener,
     ) {
         val oldLeft = this.left
         val oldTop = this.top
@@ -920,7 +924,7 @@
             left,
             top,
             right,
-            bottom
+            bottom,
         )
     }
 
@@ -941,7 +945,7 @@
                     /* left= */ insets.first,
                     /* top= */ 0,
                     /* right= */ insets.second,
-                    /* bottom= */ 0
+                    /* bottom= */ 0,
                 )
             )
         whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(cornerCutout)
@@ -968,7 +972,7 @@
                     anyInt(),
                     anyInt(),
                     anyInt(),
-                    anyInt()
+                    anyInt(),
                 )
             )
             .thenReturn(EMPTY_CHANGES)
@@ -977,7 +981,7 @@
         whenever(
                 combinedShadeHeadersConstraintManager.centerCutoutConstraints(
                     Mockito.anyBoolean(),
-                    anyInt()
+                    anyInt(),
                 )
             )
             .thenReturn(EMPTY_CHANGES)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index a75d7b2..da0029f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -21,6 +21,8 @@
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT;
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
 
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
@@ -777,6 +779,24 @@
     }
 
     @Test
+    public void indicationAreaHidden_untilBatteryInfoArrives() {
+        createController();
+        // level of -1 indicates missing info
+        BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_UNKNOWN,
+                -1 /* level */, BatteryManager.BATTERY_PLUGGED_WIRELESS, 100 /* health */,
+                0 /* maxChargingWattage */, true /* present */);
+
+        mController.setVisible(true);
+        mStatusBarStateListener.onDozingChanged(true);
+        reset(mIndicationArea);
+
+        mController.getKeyguardCallback().onRefreshBatteryInfo(status);
+        // VISIBLE is always called first
+        verify(mIndicationArea).setVisibility(VISIBLE);
+        verify(mIndicationArea).setVisibility(GONE);
+    }
+
+    @Test
     public void onRefreshBatteryInfo_computesChargingTime() throws RemoteException {
         createController();
         BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
index 4e7de81..4cad5f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
@@ -29,21 +29,24 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.privacy.OngoingPrivacyChip
 import com.android.systemui.statusbar.BatteryStatusChip
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingIn
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingOut
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimationQueued
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.RunningChipAnim
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.ShowingPersistentDot
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
-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.android.systemui.util.time.FakeSystemClock
-import junit.framework.Assert.assertEquals
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertEquals
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -54,6 +57,10 @@
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
@@ -120,12 +127,12 @@
         val batteryChip = createAndScheduleFakeBatteryEvent()
 
         // assert that animation is queued
-        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimationQueued, systemStatusAnimationScheduler.animationState.value)
 
         // skip debounce delay
         advanceTimeBy(DEBOUNCE_DELAY + 1)
         // status chip starts animating in after debounce delay
-        assertEquals(ANIMATING_IN, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimatingIn, systemStatusAnimationScheduler.animationState.value)
         assertEquals(0f, batteryChip.contentView.alpha)
         assertEquals(0f, batteryChip.view.alpha)
         verify(listener, times(1)).onSystemEventAnimationBegin()
@@ -134,14 +141,14 @@
         animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
         advanceTimeBy(APPEAR_ANIMATION_DURATION)
         // assert that status chip is visible
-        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(RunningChipAnim, systemStatusAnimationScheduler.animationState.value)
         assertEquals(1f, batteryChip.contentView.alpha)
         assertEquals(1f, batteryChip.view.alpha)
 
         // skip status chip display time
         advanceTimeBy(DISPLAY_LENGTH + 1)
-        // assert that it is still visible but switched to the ANIMATING_OUT state
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        // assert that it is still visible but switched to the AnimatingOut state
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
         assertEquals(1f, batteryChip.contentView.alpha)
         assertEquals(1f, batteryChip.view.alpha)
         verify(listener, times(1)).onSystemEventAnimationFinish(false)
@@ -149,7 +156,7 @@
         // skip disappear animation
         animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
         // assert that it is not visible anymore
-        assertEquals(IDLE, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(Idle, systemStatusAnimationScheduler.animationState.value)
         assertEquals(0f, batteryChip.contentView.alpha)
         assertEquals(0f, batteryChip.view.alpha)
     }
@@ -166,7 +173,7 @@
         createAndScheduleFakePrivacyEvent()
 
         // THEN the privacy event still happens
-        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimationQueued, systemStatusAnimationScheduler.animationState.value)
     }
 
     @Test
@@ -177,12 +184,12 @@
         val privacyChip = createAndScheduleFakePrivacyEvent()
 
         // assert that animation is queued
-        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimationQueued, systemStatusAnimationScheduler.animationState.value)
 
         // skip debounce delay
         advanceTimeBy(DEBOUNCE_DELAY + 1)
         // status chip starts animating in after debounce delay
-        assertEquals(ANIMATING_IN, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimatingIn, systemStatusAnimationScheduler.animationState.value)
         assertEquals(0f, privacyChip.view.alpha)
         verify(listener, times(1)).onSystemEventAnimationBegin()
 
@@ -190,13 +197,13 @@
         animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
         advanceTimeBy(APPEAR_ANIMATION_DURATION + 1)
         // assert that status chip is visible
-        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(RunningChipAnim, systemStatusAnimationScheduler.animationState.value)
         assertEquals(1f, privacyChip.view.alpha)
 
         // skip status chip display time
         advanceTimeBy(DISPLAY_LENGTH + 1)
-        // assert that it is still visible but switched to the ANIMATING_OUT state
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        // assert that it is still visible but switched to the AnimatingOut state
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
         assertEquals(1f, privacyChip.view.alpha)
         verify(listener, times(1)).onSystemEventAnimationFinish(true)
         verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
@@ -205,13 +212,13 @@
         advanceTimeBy(DISAPPEAR_ANIMATION_DURATION + 1)
         animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
         // assert that it the dot is now visible
-        assertEquals(SHOWING_PERSISTENT_DOT, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(ShowingPersistentDot, systemStatusAnimationScheduler.animationState.value)
         assertEquals(1f, privacyChip.view.alpha)
 
         // notify SystemStatusAnimationScheduler to remove persistent dot
         systemStatusAnimationScheduler.removePersistentDot()
-        // assert that IDLE state is entered
-        assertEquals(IDLE, systemStatusAnimationScheduler.getAnimationState())
+        // assert that Idle state is entered
+        assertEquals(Idle, systemStatusAnimationScheduler.animationState.value)
         verify(listener, times(1)).onHidePersistentDot()
     }
 
@@ -225,19 +232,19 @@
         batteryChip.view.alpha = 0f
 
         // assert that animation is queued
-        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimationQueued, systemStatusAnimationScheduler.animationState.value)
 
         // create and schedule high priority event
         val privacyChip = createAndScheduleFakePrivacyEvent()
 
         // assert that animation is queued
-        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimationQueued, systemStatusAnimationScheduler.animationState.value)
 
         // skip debounce delay and appear animation duration
-        fastForwardAnimationToState(RUNNING_CHIP_ANIM)
+        fastForwardAnimationToState(RunningChipAnim)
 
         // high priority status chip is visible while low priority status chip is not visible
-        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(RunningChipAnim, systemStatusAnimationScheduler.animationState.value)
         assertEquals(1f, privacyChip.view.alpha)
         assertEquals(0f, batteryChip.view.alpha)
     }
@@ -250,11 +257,11 @@
         // create and schedule low priority event
         val batteryChip = createAndScheduleFakeBatteryEvent()
 
-        // fast forward to RUNNING_CHIP_ANIM state
-        fastForwardAnimationToState(RUNNING_CHIP_ANIM)
+        // fast forward to RunningChipAnim state
+        fastForwardAnimationToState(RunningChipAnim)
 
         // assert that chip is displayed
-        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(RunningChipAnim, systemStatusAnimationScheduler.animationState.value)
         assertEquals(1f, batteryChip.view.alpha)
 
         // create and schedule high priority event
@@ -264,20 +271,20 @@
         testScheduler.runCurrent()
 
         // assert that currently displayed chip is immediately animated out
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
 
         // skip disappear animation
         animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
 
         // assert that high priority privacy chip animation is queued
-        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimationQueued, systemStatusAnimationScheduler.animationState.value)
 
         // skip debounce delay and appear animation
         advanceTimeBy(DEBOUNCE_DELAY + APPEAR_ANIMATION_DURATION + 1)
         animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
 
         // high priority status chip is visible while low priority status chip is not visible
-        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(RunningChipAnim, systemStatusAnimationScheduler.animationState.value)
         assertEquals(1f, privacyChip.view.alpha)
         assertEquals(0f, batteryChip.view.alpha)
     }
@@ -294,7 +301,7 @@
         advanceTimeBy(DEBOUNCE_DELAY + 1)
 
         // assert that chip is animated in
-        assertEquals(ANIMATING_IN, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimatingIn, systemStatusAnimationScheduler.animationState.value)
 
         // create and schedule high priority event
         val privacyChip = createAndScheduleFakePrivacyEvent()
@@ -303,7 +310,7 @@
         testScheduler.runCurrent()
 
         // assert that currently animated chip keeps animating
-        assertEquals(ANIMATING_IN, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimatingIn, systemStatusAnimationScheduler.animationState.value)
 
         // skip appear animation
         animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
@@ -311,20 +318,20 @@
 
         // assert that low priority chip is animated out immediately after finishing the appear
         // animation
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
 
         // skip disappear animation
         animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
 
         // assert that high priority privacy chip animation is queued
-        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimationQueued, systemStatusAnimationScheduler.animationState.value)
 
         // skip debounce delay and appear animation
         advanceTimeBy(DEBOUNCE_DELAY + APPEAR_ANIMATION_DURATION + 1)
         animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
 
         // high priority status chip is visible while low priority status chip is not visible
-        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(RunningChipAnim, systemStatusAnimationScheduler.animationState.value)
         assertEquals(1f, privacyChip.view.alpha)
         assertEquals(0f, batteryChip.view.alpha)
     }
@@ -346,7 +353,7 @@
         animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
 
         // high priority status chip is visible while low priority status chip is not visible
-        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(RunningChipAnim, systemStatusAnimationScheduler.animationState.value)
         assertEquals(1f, privacyChip.view.alpha)
         assertEquals(0f, batteryChip.view.alpha)
     }
@@ -359,14 +366,14 @@
         // create and schedule high priority event
         createAndScheduleFakePrivacyEvent()
 
-        // skip chip animation lifecycle and fast forward to SHOWING_PERSISTENT_DOT state
-        fastForwardAnimationToState(SHOWING_PERSISTENT_DOT)
-        assertEquals(SHOWING_PERSISTENT_DOT, systemStatusAnimationScheduler.getAnimationState())
+        // skip chip animation lifecycle and fast forward to ShowingPersistentDot state
+        fastForwardAnimationToState(ShowingPersistentDot)
+        assertEquals(ShowingPersistentDot, systemStatusAnimationScheduler.animationState.value)
         verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
 
-        // remove persistent dot and verify that animationState changes to IDLE
+        // remove persistent dot and verify that animationState changes to Idle
         systemStatusAnimationScheduler.removePersistentDot()
-        assertEquals(IDLE, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(Idle, systemStatusAnimationScheduler.animationState.value)
         verify(listener, times(1)).onHidePersistentDot()
     }
 
@@ -377,14 +384,14 @@
         val accessibilityDesc = "Some desc"
         val mockView = mock<View>()
         val mockAnimatableView =
-            mock<BackgroundAnimatableView> { whenever(view).thenReturn(mockView) }
+            mock<BackgroundAnimatableView> { whenever(it.view).thenReturn(mockView) }
 
         scheduleFakeEventWithView(
             accessibilityDesc,
             mockAnimatableView,
             shouldAnnounceAccessibilityEvent = true,
         )
-        fastForwardAnimationToState(ANIMATING_OUT)
+        fastForwardAnimationToState(AnimatingOut)
 
         verify(mockView).announceForAccessibility(eq(accessibilityDesc))
     }
@@ -396,14 +403,14 @@
         val accessibilityDesc = null
         val mockView = mock<View>()
         val mockAnimatableView =
-            mock<BackgroundAnimatableView> { whenever(view).thenReturn(mockView) }
+            mock<BackgroundAnimatableView> { whenever(it.view).thenReturn(mockView) }
 
         scheduleFakeEventWithView(
             accessibilityDesc,
             mockAnimatableView,
             shouldAnnounceAccessibilityEvent = true,
         )
-        fastForwardAnimationToState(ANIMATING_OUT)
+        fastForwardAnimationToState(AnimatingOut)
 
         verify(mockView, never()).announceForAccessibility(any())
     }
@@ -415,14 +422,14 @@
         val accessibilityDesc = "something"
         val mockView = mock<View>()
         val mockAnimatableView =
-            mock<BackgroundAnimatableView> { whenever(view).thenReturn(mockView) }
+            mock<BackgroundAnimatableView> { whenever(it.view).thenReturn(mockView) }
 
         scheduleFakeEventWithView(
             accessibilityDesc,
             mockAnimatableView,
             shouldAnnounceAccessibilityEvent = false,
         )
-        fastForwardAnimationToState(ANIMATING_OUT)
+        fastForwardAnimationToState(AnimatingOut)
 
         verify(mockView, never()).announceForAccessibility(any())
     }
@@ -435,21 +442,21 @@
         // create and schedule high priority event
         createAndScheduleFakePrivacyEvent()
 
-        // skip chip animation lifecycle and fast forward to RUNNING_CHIP_ANIM state
-        fastForwardAnimationToState(RUNNING_CHIP_ANIM)
-        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        // skip chip animation lifecycle and fast forward to RunningChipAnim state
+        fastForwardAnimationToState(RunningChipAnim)
+        assertEquals(RunningChipAnim, systemStatusAnimationScheduler.animationState.value)
 
         // request removal of persistent dot
         systemStatusAnimationScheduler.removePersistentDot()
 
         // skip display time and verify that disappear animation is run
         advanceTimeBy(DISPLAY_LENGTH + 1)
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
 
-        // skip disappear animation and verify that animationState changes to IDLE instead of
-        // SHOWING_PERSISTENT_DOT
+        // skip disappear animation and verify that animationState changes to Idle instead of
+        // ShowingPersistentDot
         animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
-        assertEquals(IDLE, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(Idle, systemStatusAnimationScheduler.animationState.value)
         // verify that the persistent dot callbacks are not invoked
         verify(listener, never()).onSystemStatusAnimationTransitionToPersistentDot(any())
         verify(listener, never()).onHidePersistentDot()
@@ -463,9 +470,9 @@
         // create and schedule high priority event
         createAndScheduleFakePrivacyEvent()
 
-        // fast forward to ANIMATING_OUT state
-        fastForwardAnimationToState(ANIMATING_OUT)
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        // fast forward to AnimatingOut state
+        fastForwardAnimationToState(AnimatingOut)
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
         verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
 
         // remove persistent dot
@@ -478,8 +485,8 @@
         animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
         testScheduler.runCurrent()
 
-        // verify that animationState changes to IDLE
-        assertEquals(IDLE, systemStatusAnimationScheduler.getAnimationState())
+        // verify that animationState changes to Idle
+        assertEquals(Idle, systemStatusAnimationScheduler.animationState.value)
     }
 
     @Test
@@ -494,11 +501,11 @@
         // create and schedule a privacy event again (resets forceVisible to true)
         createAndScheduleFakePrivacyEvent()
 
-        // skip chip animation lifecycle and fast forward to SHOWING_PERSISTENT_DOT state
-        fastForwardAnimationToState(SHOWING_PERSISTENT_DOT)
+        // skip chip animation lifecycle and fast forward to ShowingPersistentDot state
+        fastForwardAnimationToState(ShowingPersistentDot)
 
-        // verify that we reach SHOWING_PERSISTENT_DOT and that listener callback is invoked
-        assertEquals(SHOWING_PERSISTENT_DOT, systemStatusAnimationScheduler.getAnimationState())
+        // verify that we reach ShowingPersistentDot and that listener callback is invoked
+        assertEquals(ShowingPersistentDot, systemStatusAnimationScheduler.animationState.value)
         verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
     }
 
@@ -511,21 +518,21 @@
         createAndScheduleFakePrivacyEvent()
         // request removal of persistent dot (sets forceVisible to false)
         systemStatusAnimationScheduler.removePersistentDot()
-        fastForwardAnimationToState(RUNNING_CHIP_ANIM)
+        fastForwardAnimationToState(RunningChipAnim)
 
         // create and schedule a privacy event again (resets forceVisible to true)
         createAndScheduleFakePrivacyEvent()
 
         // skip status chip display time
         advanceTimeBy(DISPLAY_LENGTH + 1)
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
         verify(listener, times(1)).onSystemEventAnimationFinish(anyBoolean())
 
         // skip disappear animation
         animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
 
-        // verify that we reach SHOWING_PERSISTENT_DOT and that listener callback is invoked
-        assertEquals(SHOWING_PERSISTENT_DOT, systemStatusAnimationScheduler.getAnimationState())
+        // verify that we reach ShowingPersistentDot and that listener callback is invoked
+        assertEquals(ShowingPersistentDot, systemStatusAnimationScheduler.animationState.value)
         verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
     }
 
@@ -537,9 +544,9 @@
         // create and schedule high priority event
         createAndScheduleFakePrivacyEvent()
 
-        // skip chip animation lifecycle and fast forward to ANIMATING_OUT state
-        fastForwardAnimationToState(ANIMATING_OUT)
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        // skip chip animation lifecycle and fast forward to AnimatingOut state
+        fastForwardAnimationToState(AnimatingOut)
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
         verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
 
         // request removal of persistent dot
@@ -548,13 +555,13 @@
         // schedule another high priority event while the event is animating out
         createAndScheduleFakePrivacyEvent()
 
-        // verify that the state is still ANIMATING_OUT
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        // verify that the state is still AnimatingOut
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
 
-        // skip disappear animation duration and verify that new state is ANIMATION_QUEUED
+        // skip disappear animation duration and verify that new state is AnimationQueued
         animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
         testScheduler.runCurrent()
-        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimationQueued, systemStatusAnimationScheduler.animationState.value)
         // also verify that onHidePersistentDot callback is called
         verify(listener, times(1)).onHidePersistentDot()
     }
@@ -567,16 +574,16 @@
         // create and schedule high priority event
         createAndScheduleFakePrivacyEvent()
 
-        // skip chip animation lifecycle and fast forward to ANIMATING_OUT state
-        fastForwardAnimationToState(ANIMATING_OUT)
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        // skip chip animation lifecycle and fast forward to AnimatingOut state
+        fastForwardAnimationToState(AnimatingOut)
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
         verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
 
         // request removal of persistent dot
         systemStatusAnimationScheduler.removePersistentDot()
 
-        // verify that the state is still ANIMATING_OUT
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        // verify that the state is still AnimatingOut
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
 
         // skip disappear animation duration
         testScheduler.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION + 1)
@@ -591,33 +598,33 @@
         // verify that onHidePersistentDot is invoked despite the animator callback being delayed
         // (it's invoked more than DISAPPEAR_ANIMATION_DURATION after the dot removal was requested)
         verify(listener, times(1)).onHidePersistentDot()
-        // verify that animationState is IDLE
-        assertEquals(IDLE, systemStatusAnimationScheduler.getAnimationState())
+        // verify that animationState is Idle
+        assertEquals(Idle, systemStatusAnimationScheduler.animationState.value)
     }
 
-    private fun TestScope.fastForwardAnimationToState(@SystemAnimationState animationState: Int) {
+    private fun TestScope.fastForwardAnimationToState(animationState: SystemEventAnimationState) {
         // this function should only be called directly after posting a status event
-        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
-        if (animationState == IDLE || animationState == ANIMATION_QUEUED) return
+        assertEquals(AnimationQueued, systemStatusAnimationScheduler.animationState.value)
+        if (animationState == Idle || animationState == AnimationQueued) return
         // skip debounce delay
         advanceTimeBy(DEBOUNCE_DELAY + 1)
 
         // status chip starts animating in after debounce delay
-        assertEquals(ANIMATING_IN, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimatingIn, systemStatusAnimationScheduler.animationState.value)
         verify(listener, times(1)).onSystemEventAnimationBegin()
-        if (animationState == ANIMATING_IN) return
+        if (animationState == AnimatingIn) return
 
         // skip appear animation
         animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
         advanceTimeBy(APPEAR_ANIMATION_DURATION)
-        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
-        if (animationState == RUNNING_CHIP_ANIM) return
+        assertEquals(RunningChipAnim, systemStatusAnimationScheduler.animationState.value)
+        if (animationState == RunningChipAnim) return
 
         // skip status chip display time
         advanceTimeBy(DISPLAY_LENGTH + 1)
-        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(AnimatingOut, systemStatusAnimationScheduler.animationState.value)
         verify(listener, times(1)).onSystemEventAnimationFinish(anyBoolean())
-        if (animationState == ANIMATING_OUT) return
+        if (animationState == AnimatingOut) return
 
         // skip disappear animation
         animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 87cda64..fdfc253 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -244,7 +244,7 @@
         when(mStackSizeCalculator.computeHeight(eq(mStackScroller), anyInt(), anyFloat()))
                 .thenReturn((float) stackHeight);
 
-        mStackScroller.updateStackHeight();
+        mStackScroller.updateIntrinsicStackHeight();
 
         assertThat(mStackScroller.getIntrinsicStackHeight()).isEqualTo(stackHeight);
     }
@@ -1218,7 +1218,38 @@
     }
 
     @Test
-    @DisableSceneContainer // TODO(b/312473478): address disabled test
+    @EnableSceneContainer
+    public void testSetMaxDisplayedNotifications_updatesStackHeight() {
+        int fullStackHeight = 300;
+        int limitedStackHeight = 100;
+        int maxNotifs = 2; // any non-zero limit
+        float stackTop = 100;
+        float stackCutoff = 1100;
+        float stackViewPortHeight = stackCutoff - stackTop;
+        mStackScroller.setStackTop(stackTop);
+        mStackScroller.setStackCutoff(stackCutoff);
+        when(mStackSizeCalculator.computeHeight(eq(mStackScroller), eq(-1), anyFloat()))
+                .thenReturn((float) fullStackHeight);
+        when(mStackSizeCalculator.computeHeight(eq(mStackScroller), eq(maxNotifs), anyFloat()))
+                .thenReturn((float) limitedStackHeight);
+
+        // When we set a limit on max displayed notifications
+        mStackScroller.setMaxDisplayedNotifications(maxNotifs);
+
+        // Then
+        assertThat(mStackScroller.getIntrinsicStackHeight()).isEqualTo(limitedStackHeight);
+        assertThat(mAmbientState.getStackEndHeight()).isEqualTo(limitedStackHeight);
+
+        // When there is no limit on max displayed notifications
+        mStackScroller.setMaxDisplayedNotifications(-1);
+
+        // Then
+        assertThat(mStackScroller.getIntrinsicStackHeight()).isEqualTo(fullStackHeight);
+        assertThat(mAmbientState.getStackEndHeight()).isEqualTo(stackViewPortHeight);
+    }
+
+    @Test
+    @DisableSceneContainer
     public void testSetMaxDisplayedNotifications_notifiesListeners() {
         ExpandableView.OnHeightChangedListener listener =
                 mock(ExpandableView.OnHeightChangedListener.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 83d0bcc..008e8ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -37,7 +37,6 @@
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.plugins.fakeDarkIconDispatcher
 import com.android.systemui.res.R
 import com.android.systemui.scene.ui.view.WindowRootView
@@ -46,9 +45,12 @@
 import com.android.systemui.shade.ShadeViewController
 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
 import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.data.repository.fakeStatusBarContentInsetsProviderStore
+import com.android.systemui.statusbar.data.repository.statusBarContentInsetsProviderStore
 import com.android.systemui.statusbar.policy.Clock
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.window.StatusBarWindowStateController
+import com.android.systemui.testKosmos
 import com.android.systemui.unfold.SysUIUnfoldComponent
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
 import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
@@ -75,7 +77,9 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PhoneStatusBarViewControllerTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
+    private val statusBarContentInsetsProviderStore = kosmos.fakeStatusBarContentInsetsProviderStore
+    private val statusBarContentInsetsProvider = statusBarContentInsetsProviderStore.defaultDisplay
 
     private val fakeDarkIconDispatcher = kosmos.fakeDarkIconDispatcher
     @Mock private lateinit var shadeViewController: ShadeViewController
@@ -93,7 +97,6 @@
     @Mock private lateinit var windowRootView: Provider<WindowRootView>
     @Mock private lateinit var shadeLogger: ShadeLogger
     @Mock private lateinit var viewUtil: ViewUtil
-    @Mock private lateinit var statusBarContentInsetsProvider: StatusBarContentInsetsProvider
     private lateinit var statusBarWindowStateController: StatusBarWindowStateController
 
     private lateinit var view: PhoneStatusBarView
@@ -396,7 +399,7 @@
                 configurationController,
                 mStatusOverlayHoverListenerFactory,
                 fakeDarkIconDispatcher,
-                statusBarContentInsetsProvider,
+                statusBarContentInsetsProviderStore,
             )
             .create(view)
             .also { it.init() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/CameraProtectionLoaderKosmos.kt
similarity index 70%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/CameraProtectionLoaderKosmos.kt
index daf6087..7625049 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/CameraProtectionLoaderKosmos.kt
@@ -14,10 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.panels.ui.viewmodel
+package com.android.systemui
 
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.domain.interactor.iconLabelVisibilityInteractor
 
-val Kosmos.iconLabelVisibilityViewModel by
-    Kosmos.Fixture { IconLabelVisibilityViewModelImpl(iconLabelVisibilityInteractor) }
+val Kosmos.fakeCameraProtectionLoaderFactory by
+    Kosmos.Fixture { FakeCameraProtectionLoaderFactory() }
+
+var Kosmos.cameraProtectionLoaderFactory: CameraProtectionLoaderImpl.Factory by
+    Kosmos.Fixture { fakeCameraProtectionLoaderFactory }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/FakeCameraProtectionLoaderFactory.kt
similarity index 66%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/FakeCameraProtectionLoaderFactory.kt
index daf6087..87428b0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/FakeCameraProtectionLoaderFactory.kt
@@ -14,10 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.panels.ui.viewmodel
+package com.android.systemui
 
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.domain.interactor.iconLabelVisibilityInteractor
+import android.content.Context
+import org.mockito.kotlin.mock
 
-val Kosmos.iconLabelVisibilityViewModel by
-    Kosmos.Fixture { IconLabelVisibilityViewModelImpl(iconLabelVisibilityInteractor) }
+class FakeCameraProtectionLoaderFactory : CameraProtectionLoaderImpl.Factory {
+
+    override fun create(context: Context): CameraProtectionLoaderImpl {
+        return mock<CameraProtectionLoaderImpl>()
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/FakeSysUICutoutProviderFactory.kt
similarity index 62%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/FakeSysUICutoutProviderFactory.kt
index daf6087..4eb3780 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/FakeSysUICutoutProviderFactory.kt
@@ -14,10 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.panels.ui.viewmodel
+package com.android.systemui
 
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.domain.interactor.iconLabelVisibilityInteractor
+import android.content.Context
+import org.mockito.kotlin.mock
 
-val Kosmos.iconLabelVisibilityViewModel by
-    Kosmos.Fixture { IconLabelVisibilityViewModelImpl(iconLabelVisibilityInteractor) }
+class FakeSysUICutoutProviderFactory : SysUICutoutProviderImpl.Factory {
+
+    override fun create(
+        context: Context,
+        cameraProtectionLoader: CameraProtectionLoader,
+    ): SysUICutoutProviderImpl {
+        return mock<SysUICutoutProviderImpl>()
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/SysUICutoutProviderKosmos.kt
similarity index 70%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/SysUICutoutProviderKosmos.kt
index daf6087..412ed72 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysUICutoutProviderKosmos.kt
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.panels.ui.viewmodel
+package com.android.systemui
 
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.domain.interactor.iconLabelVisibilityInteractor
 
-val Kosmos.iconLabelVisibilityViewModel by
-    Kosmos.Fixture { IconLabelVisibilityViewModelImpl(iconLabelVisibilityInteractor) }
+val Kosmos.fakeSysUICutoutProviderFactory by Kosmos.Fixture { FakeSysUICutoutProviderFactory() }
+
+var Kosmos.sysUICutoutProviderFactory: SysUICutoutProviderImpl.Factory by
+    Kosmos.Fixture { fakeSysUICutoutProviderFactory }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt
index 3fd2503..93e7f2e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorKosmos.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.education.domain.interactor
 
 import android.hardware.input.InputManager
+import com.android.systemui.education.ContextualEducationMetricsLogger
 import com.android.systemui.education.data.repository.fakeEduClock
 import com.android.systemui.inputdevice.data.repository.UserInputDeviceRepository
 import com.android.systemui.inputdevice.tutorial.tutorialSchedulerRepository
@@ -41,11 +42,13 @@
                     touchpadRepository,
                     userRepository,
                 ),
-            tutorialSchedulerRepository,
-            mockOverviewProxyService,
+            tutorialRepository = tutorialSchedulerRepository,
+            overviewProxyService = mockOverviewProxyService,
+            metricsLogger = mockEduMetricsLogger,
             clock = fakeEduClock,
         )
     }
 
+var Kosmos.mockEduMetricsLogger by Kosmos.Fixture { mock<ContextualEducationMetricsLogger>() }
 var Kosmos.mockOverviewProxyService by Kosmos.Fixture { mock<OverviewProxyService>() }
 var Kosmos.mockEduInputManager by Kosmos.Fixture { mock<InputManager>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
index 9593dfb..8c4ec4c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
@@ -28,8 +28,6 @@
 import com.android.systemui.power.domain.interactor.PowerInteractorFactory
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.shade.data.repository.FakeShadeRepository
-import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
-import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor.ConfigurationBasedDimensions
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import kotlinx.coroutines.CoroutineScope
@@ -56,7 +54,6 @@
         fromGoneTransitionInteractor: FromGoneTransitionInteractor = mock(),
         fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor = mock(),
         fromOccludedTransitionInteractor: FromOccludedTransitionInteractor = mock(),
-        sharedNotificationContainerInteractor: SharedNotificationContainerInteractor? = null,
         powerInteractor: PowerInteractor = PowerInteractorFactory.create().powerInteractor,
         testScope: CoroutineScope = TestScope(),
     ): WithDependencies {
@@ -69,23 +66,6 @@
                 whenever(it.transitionState).thenReturn(transitionStateFlow)
                 whenever(it.isFinishedIn(any(), any())).thenReturn(MutableStateFlow(false))
             }
-        val configurationDimensionFlow = MutableSharedFlow<ConfigurationBasedDimensions>()
-        configurationDimensionFlow.tryEmit(
-            ConfigurationBasedDimensions(
-                useSplitShade = false,
-                useLargeScreenHeader = false,
-                marginHorizontal = 0,
-                marginBottom = 0,
-                marginTop = 0,
-                marginTopLargeScreen = 0,
-                keyguardSplitShadeTopMargin = 0,
-            )
-        )
-        val sncInteractor =
-            sharedNotificationContainerInteractor
-                ?: mock<SharedNotificationContainerInteractor>().also {
-                    whenever(it.configurationBasedDimensions).thenReturn(configurationDimensionFlow)
-                }
         return WithDependencies(
             repository = repository,
             featureFlags = featureFlags,
@@ -104,7 +84,6 @@
                 fromGoneTransitionInteractor = { fromGoneTransitionInteractor },
                 fromLockscreenTransitionInteractor = { fromLockscreenTransitionInteractor },
                 fromOccludedTransitionInteractor = { fromOccludedTransitionInteractor },
-                sharedNotificationContainerInteractor = { sncInteractor },
                 applicationScope = testScope,
             ),
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
index e85114d..da261bf 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
@@ -24,7 +24,6 @@
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
 
 val Kosmos.keyguardInteractor: KeyguardInteractor by
     Kosmos.Fixture {
@@ -39,7 +38,6 @@
             fromGoneTransitionInteractor = { fromGoneTransitionInteractor },
             fromLockscreenTransitionInteractor = { fromLockscreenTransitionInteractor },
             fromOccludedTransitionInteractor = { fromOccludedTransitionInteractor },
-            sharedNotificationContainerInteractor = { sharedNotificationContainerInteractor },
             applicationScope = testScope.backgroundScope,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorKosmos.kt
deleted file mode 100644
index 954084b..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorKosmos.kt
+++ /dev/null
@@ -1,30 +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.qs.panels.domain.interactor
-
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
-import com.android.systemui.log.core.FakeLogBuffer
-
-val Kosmos.iconLabelVisibilityInteractor by
-    Kosmos.Fixture {
-        IconLabelVisibilityInteractor(
-            qsPreferencesInteractor,
-            FakeLogBuffer.Factory.create(),
-            applicationCoroutineScope
-        )
-    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
index 10d8e1e..48ef57e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
@@ -25,7 +25,6 @@
         PaginatedGridViewModel(
             iconTilesViewModel,
             qsColumnsViewModel,
-            iconLabelVisibilityViewModel,
             paginatedGridInteractor,
             applicationCoroutineScope,
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
index 60141c6..6944e6c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
@@ -187,6 +187,7 @@
         context
             .getOrCreateTestableResources()
             .addOverride(R.bool.config_use_split_notification_shade, splitShade)
+        shadeRepository.setShadeLayoutWide(splitShade)
         testScope.runCurrent()
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
index 92075ea..39f58ae 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.shade.ShadeModule
 import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.statusbar.disableflags.data.repository.disableFlagsRepository
-import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
 import com.android.systemui.statusbar.phone.dozeParameters
 import com.android.systemui.statusbar.policy.data.repository.userSetupRepository
 import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor
@@ -52,7 +51,6 @@
         ShadeInteractorLegacyImpl(
             scope = applicationCoroutineScope,
             keyguardRepository = keyguardRepository,
-            sharedNotificationContainerInteractor = sharedNotificationContainerInteractor,
             repository = shadeRepository,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeStatusBarConfigurationControllerStore.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeStatusBarConfigurationControllerStore.kt
new file mode 100644
index 0000000..46bb2c1
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeStatusBarConfigurationControllerStore.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.data.repository
+
+import android.view.Display
+import org.mockito.kotlin.mock
+
+class FakeStatusBarConfigurationControllerStore : StatusBarConfigurationControllerStore {
+
+    private val perDisplayMockControllers = mutableMapOf<Int, StatusBarConfigurationController>()
+
+    override val defaultDisplay: StatusBarConfigurationController
+        get() = forDisplay(Display.DEFAULT_DISPLAY)
+
+    override fun forDisplay(displayId: Int): StatusBarConfigurationController {
+        return perDisplayMockControllers.computeIfAbsent(displayId) { mock() }
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeStatusBarContentInsetsProviderStore.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeStatusBarContentInsetsProviderStore.kt
new file mode 100644
index 0000000..642c2ff
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeStatusBarContentInsetsProviderStore.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.statusbar.data.repository
+
+import android.view.Display
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import org.mockito.kotlin.mock
+
+class FakeStatusBarContentInsetsProviderStore() : StatusBarContentInsetsProviderStore {
+
+    private val perDisplayMockProviders = mutableMapOf<Int, StatusBarContentInsetsProvider>()
+
+    override val defaultDisplay: StatusBarContentInsetsProvider
+        get() = forDisplay(Display.DEFAULT_DISPLAY)
+
+    override fun forDisplay(displayId: Int): StatusBarContentInsetsProvider {
+        return perDisplayMockProviders.computeIfAbsent(displayId) { mock() }
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStoreKosmos.kt
similarity index 66%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStoreKosmos.kt
index daf6087..03b63c2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStoreKosmos.kt
@@ -14,10 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.panels.ui.viewmodel
+package com.android.systemui.statusbar.data.repository
 
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.domain.interactor.iconLabelVisibilityInteractor
 
-val Kosmos.iconLabelVisibilityViewModel by
-    Kosmos.Fixture { IconLabelVisibilityViewModelImpl(iconLabelVisibilityInteractor) }
+val Kosmos.fakeStatusBarConfigurationControllerStore by Kosmos.Fixture {
+    FakeStatusBarConfigurationControllerStore()
+}
+
+var Kosmos.statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore by
+    Kosmos.Fixture { fakeStatusBarConfigurationControllerStore }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStoreKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStoreKosmos.kt
new file mode 100644
index 0000000..a34fb09
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStoreKosmos.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.statusbar.data.repository
+
+import com.android.systemui.cameraProtectionLoaderFactory
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.display.data.repository.displayWindowPropertiesRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.phone.statusBarContentInsetsProviderFactory
+import com.android.systemui.sysUICutoutProviderFactory
+
+val Kosmos.fakeStatusBarContentInsetsProviderStore by
+    Kosmos.Fixture { FakeStatusBarContentInsetsProviderStore() }
+
+val Kosmos.multiDisplayStatusBarContentInsetsProviderStore by
+    Kosmos.Fixture {
+        MultiDisplayStatusBarContentInsetsProviderStore(
+            applicationCoroutineScope,
+            displayRepository,
+            statusBarContentInsetsProviderFactory,
+            displayWindowPropertiesRepository,
+            statusBarConfigurationControllerStore,
+            sysUICutoutProviderFactory,
+            cameraProtectionLoaderFactory,
+        )
+    }
+
+var Kosmos.statusBarContentInsetsProviderStore: StatusBarContentInsetsProviderStore by
+    Kosmos.Fixture { fakeStatusBarContentInsetsProviderStore }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorKosmos.kt
index 3234e66..83fc3e9 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorKosmos.kt
@@ -14,26 +14,29 @@
  * limitations under the License.
  */
 
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
 package com.android.systemui.statusbar.notification.stack.domain.interactor
 
 import android.content.applicationContext
-import com.android.systemui.common.ui.data.repository.configurationRepository
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.shade.largeScreenHeaderHelper
 import com.android.systemui.statusbar.policy.splitShadeStateController
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 
 val Kosmos.sharedNotificationContainerInteractor by
     Kosmos.Fixture {
         SharedNotificationContainerInteractor(
-            configurationRepository = configurationRepository,
             context = applicationContext,
             splitShadeStateController = { splitShadeStateController },
             shadeInteractor = { shadeInteractor },
+            configurationInteractor = configurationInteractor,
             keyguardInteractor = keyguardInteractor,
             deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
-            largeScreenHeaderHelperLazy = { largeScreenHeaderHelper }
+            largeScreenHeaderHelperLazy = { largeScreenHeaderHelper },
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/FakeStatusBarContentInsetsProviderFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/FakeStatusBarContentInsetsProviderFactory.kt
new file mode 100644
index 0000000..4fb8cf4
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/FakeStatusBarContentInsetsProviderFactory.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.statusbar.phone
+
+import android.content.Context
+import com.android.systemui.SysUICutoutProvider
+import com.android.systemui.statusbar.policy.ConfigurationController
+import org.mockito.kotlin.mock
+
+class FakeStatusBarContentInsetsProviderFactory : StatusBarContentInsetsProviderImpl.Factory {
+
+    override fun create(
+        context: Context,
+        configurationController: ConfigurationController,
+        sysUICutoutProvider: SysUICutoutProvider,
+    ): StatusBarContentInsetsProviderImpl {
+        return mock<StatusBarContentInsetsProviderImpl>()
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderKosmos.kt
index 9c9673c..705df3c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderKosmos.kt
@@ -23,3 +23,9 @@
     Kosmos.Fixture { mock<StatusBarContentInsetsProvider>() }
 
 var Kosmos.statusBarContentInsetsProvider by Kosmos.Fixture { mockStatusBarContentInsetsProvider }
+
+val Kosmos.fakeStatusBarContentInsetsProviderFactory by
+    Kosmos.Fixture { FakeStatusBarContentInsetsProviderFactory() }
+
+var Kosmos.statusBarContentInsetsProviderFactory: StatusBarContentInsetsProviderImpl.Factory by
+    Kosmos.Fixture { fakeStatusBarContentInsetsProviderFactory }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowControllerFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowControllerFactory.kt
index 65247a5..7eaecb1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowControllerFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowControllerFactory.kt
@@ -19,11 +19,13 @@
 import android.content.Context
 import com.android.app.viewcapture.ViewCaptureAwareWindowManager
 import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 
 class FakeStatusBarWindowControllerFactory : StatusBarWindowController.Factory {
     override fun create(
         context: Context,
         viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager,
         statusBarConfigurationController: StatusBarConfigurationController,
+        contentInsetsProvider: StatusBarContentInsetsProvider,
     ) = FakeStatusBarWindowController()
 }
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 5911070..51034d2 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -628,16 +628,25 @@
 
         @Override
         public void enablePermissionsSync(int associationId) {
+            if (getCallingUid() != SYSTEM_UID) {
+                throw new SecurityException("Caller must be system UID");
+            }
             mSystemDataTransferProcessor.enablePermissionsSync(associationId);
         }
 
         @Override
         public void disablePermissionsSync(int associationId) {
+            if (getCallingUid() != SYSTEM_UID) {
+                throw new SecurityException("Caller must be system UID");
+            }
             mSystemDataTransferProcessor.disablePermissionsSync(associationId);
         }
 
         @Override
         public PermissionSyncRequest getPermissionSyncRequest(int associationId) {
+            if (getCallingUid() != SYSTEM_UID) {
+                throw new SecurityException("Caller must be system UID");
+            }
             return mSystemDataTransferProcessor.getPermissionSyncRequest(associationId);
         }
 
diff --git a/services/core/java/com/android/server/TradeInModeService.java b/services/core/java/com/android/server/TradeInModeService.java
new file mode 100644
index 0000000..9ad550b
--- /dev/null
+++ b/services/core/java/com/android/server/TradeInModeService.java
@@ -0,0 +1,342 @@
+/*
+ * 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;
+
+import static com.android.tradeinmode.flags.Flags.enableTradeInMode;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.OnAccountsUpdateListener;
+import android.annotation.RequiresPermission;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.ITradeInMode;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.service.persistentdata.PersistentDataBlockManager;
+import android.util.Slog;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+
+public final class TradeInModeService extends SystemService {
+    private static final String TAG = "TradeInModeService";
+
+    private static final String TIM_PROP = "persist.adb.tradeinmode";
+
+    private static final int TIM_STATE_UNSET = 0;
+
+    // adbd_tradeinmode was stopped.
+    private static final int TIM_STATE_DISABLED = -1;
+
+    // adbd_tradeinmode has started.
+    private static final int TIM_STATE_FOYER = 1;
+
+    // Full non-root adb granted; factory reset is guaranteed.
+    private static final int TIM_STATE_EVALUATION_MODE = 2;
+
+    // This file contains a single integer counter of how many boot attempts
+    // have been made since entering evaluation mode.
+    private static final String WIPE_INDICATOR_FILE = "/metadata/tradeinmode/wipe";
+
+    private final Context mContext;
+    private TradeInMode mTradeInMode;
+
+    private ConnectivityManager mConnectivityManager;
+    private ConnectivityManager.NetworkCallback mNetworkCallback = null;
+
+    private AccountManager mAccountManager;
+    private OnAccountsUpdateListener mAccountsListener = null;
+
+    public TradeInModeService(Context context) {
+        super(context);
+
+        mContext = context;
+    }
+
+    @Override
+    public void onStart() {
+        if (!enableTradeInMode()) {
+            return;
+        }
+
+        mTradeInMode = new TradeInMode();
+        publishBinderService("tradeinmode", mTradeInMode);
+    }
+
+    @Override
+    public void onBootPhase(@BootPhase int phase) {
+        if (phase == PHASE_SYSTEM_SERVICES_READY) {
+            final int state = getTradeInModeState();
+
+            if (isAdbEnabled() && !isDebuggable() && !isDeviceSetup()
+                    && state == TIM_STATE_DISABLED) {
+                // If we fail to start trade-in mode, the persist property may linger
+                // past reboot. If we detect this, disable ADB and clear TIM state.
+                Slog.i(TAG, "Resetting trade-in mode state.");
+                SystemProperties.set(TIM_PROP, "");
+
+                final ContentResolver cr = mContext.getContentResolver();
+                Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 0);
+            } else if (state == TIM_STATE_FOYER) {
+                // If zygote crashed or we rebooted, and TIM is still enabled, make
+                // sure it's allowed to be enabled. If it is, we need to re-add our
+                // setup completion observer.
+                if (isDeviceSetup()) {
+                    stopTradeInMode();
+                } else {
+                    watchForSetupCompletion();
+                }
+            }
+        }
+    }
+
+    private final class TradeInMode extends ITradeInMode.Stub {
+        @Override
+        @RequiresPermission(android.Manifest.permission.ENTER_TRADE_IN_MODE)
+        public boolean start() {
+            mContext.enforceCallingOrSelfPermission("android.permission.ENTER_TRADE_IN_MODE",
+                                                    "Cannot enter trade-in mode foyer");
+            final int state = getTradeInModeState();
+            if (state == TIM_STATE_FOYER) {
+                return true;
+            }
+
+            if (state != TIM_STATE_UNSET) {
+                Slog.e(TAG, "Cannot enter trade-in mode in state: " + state);
+                return false;
+            }
+
+            if (isDeviceSetup()) {
+                Slog.i(TAG, "Not starting trade-in mode, device is setup.");
+                return false;
+            }
+            if (SystemProperties.getInt("ro.debuggable", 0) == 1) {
+                // We don't want to force adbd into TIM on debug builds.
+                Slog.e(TAG, "Not starting trade-in mode, device is debuggable.");
+                return false;
+            }
+            if (isAdbEnabled()) {
+                Slog.e(TAG, "Not starting trade-in mode, adb is already enabled.");
+                return false;
+            }
+
+            final long callingId = Binder.clearCallingIdentity();
+            try {
+                startTradeInMode();
+            } finally {
+                Binder.restoreCallingIdentity(callingId);
+            }
+            return true;
+        }
+
+        @Override
+        @RequiresPermission(android.Manifest.permission.ENTER_TRADE_IN_MODE)
+        public boolean enterEvaluationMode() {
+            mContext.enforceCallingOrSelfPermission("android.permission.ENTER_TRADE_IN_MODE",
+                                                    "Cannot enter trade-in evaluation mode");
+            final int state = getTradeInModeState();
+            if (state != TIM_STATE_FOYER) {
+                Slog.e(TAG, "Cannot enter evaluation mode in state: " + state);
+                return false;
+            }
+            if (isFrpActive()) {
+                Slog.e(TAG, "Cannot enter evaluation mode, FRP lock is present.");
+                return false;
+            }
+
+            try (FileWriter fw = new FileWriter(WIPE_INDICATOR_FILE,
+                                                StandardCharsets.US_ASCII)) {
+                fw.write("0");
+            } catch (IOException e) {
+                Slog.e(TAG, "Failed to write " + WIPE_INDICATOR_FILE, e);
+                return false;
+            }
+
+            final long callingId = Binder.clearCallingIdentity();
+            try {
+                removeNetworkWatch();
+                removeAccountsWatch();
+            } finally {
+                Binder.restoreCallingIdentity(callingId);
+            }
+
+            SystemProperties.set(TIM_PROP, Integer.toString(TIM_STATE_EVALUATION_MODE));
+            SystemProperties.set("ctl.restart", "adbd");
+            return true;
+        }
+
+        @Override
+        @RequiresPermission(android.Manifest.permission.ENTER_TRADE_IN_MODE)
+        public boolean isEvaluationModeAllowed() {
+            mContext.enforceCallingOrSelfPermission("android.permission.ENTER_TRADE_IN_MODE",
+                                        "Cannot test for trade-in evaluation mode allowed");
+            return !isFrpActive();
+        }
+    }
+
+    private void startTradeInMode() {
+        Slog.i(TAG, "Enabling trade-in mode.");
+
+        SystemProperties.set(TIM_PROP, Integer.toString(TIM_STATE_FOYER));
+
+        final ContentResolver cr = mContext.getContentResolver();
+        Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1);
+
+        watchForSetupCompletion();
+        watchForNetworkChange();
+        watchForAccountsCreated();
+    }
+
+    private void stopTradeInMode() {
+        Slog.i(TAG, "Stopping trade-in mode.");
+
+        SystemProperties.set(TIM_PROP, Integer.toString(TIM_STATE_DISABLED));
+
+        removeNetworkWatch();
+        removeAccountsWatch();
+
+        final ContentResolver cr = mContext.getContentResolver();
+        Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 0);
+    }
+
+    private int getTradeInModeState() {
+        return SystemProperties.getInt(TIM_PROP, TIM_STATE_UNSET);
+    }
+
+    private boolean isDebuggable() {
+        return SystemProperties.getInt("ro.debuggable", 0) == 1;
+    }
+
+    private boolean isAdbEnabled() {
+        final ContentResolver cr = mContext.getContentResolver();
+        return Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0) == 1;
+    }
+
+    private boolean isFrpActive() {
+        try {
+            PersistentDataBlockManager pdb =
+                    mContext.getSystemService(PersistentDataBlockManager.class);
+            if (pdb == null) {
+                return false;
+            }
+            return pdb.isFactoryResetProtectionActive();
+        } catch (Exception e) {
+            Slog.e(TAG, "Could not read PDB", e);
+            return false;
+        }
+    }
+
+    // This returns true if the device has progressed far enough into Setup Wizard that it no
+    // longer makes sense to enable trade-in mode. As a last stop, we check the SUW completion
+    // bits.
+    private boolean isDeviceSetup() {
+        final ContentResolver cr = mContext.getContentResolver();
+        try {
+            if (Settings.Secure.getIntForUser(cr, Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
+                return true;
+            }
+        } catch (SettingNotFoundException e) {
+            Slog.e(TAG, "Could not find USER_SETUP_COMPLETE setting", e);
+        }
+
+        if (Settings.Global.getInt(cr, Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
+            return true;
+        }
+        return false;
+    }
+
+    private final class SettingsObserver extends ContentObserver {
+        SettingsObserver() {
+            super(null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            if (getTradeInModeState() == TIM_STATE_FOYER && isDeviceSetup()) {
+                stopTradeInMode();
+            }
+        }
+    }
+
+    private void watchForSetupCompletion() {
+        final Uri userSetupComplete = Settings.Secure.getUriFor(
+                Settings.Secure.USER_SETUP_COMPLETE);
+        final Uri deviceProvisioned = Settings.Global.getUriFor(
+                Settings.Global.DEVICE_PROVISIONED);
+        final ContentResolver cr = mContext.getContentResolver();
+        final SettingsObserver observer = new SettingsObserver();
+
+        cr.registerContentObserver(userSetupComplete, false, observer);
+        cr.registerContentObserver(deviceProvisioned, false, observer);
+    }
+
+
+    private void watchForNetworkChange() {
+        mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
+        NetworkRequest networkRequest = new NetworkRequest.Builder()
+                    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+                    .build();
+
+        mNetworkCallback = new ConnectivityManager.NetworkCallback() {
+            @Override
+            public void onAvailable(Network network) {
+                super.onAvailable(network);
+                stopTradeInMode();
+            }
+        };
+
+        mConnectivityManager.registerNetworkCallback(networkRequest, mNetworkCallback);
+    }
+
+    private void removeNetworkWatch() {
+        if (mNetworkCallback != null) {
+            mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+            mNetworkCallback = null;
+        }
+    }
+
+    private void watchForAccountsCreated() {
+        mAccountManager = mContext.getSystemService(AccountManager.class);
+        mAccountsListener = new OnAccountsUpdateListener() {
+            @Override
+            public void onAccountsUpdated(Account[] accounts) {
+                stopTradeInMode();
+            }
+        };
+        mAccountManager.addOnAccountsUpdatedListener(mAccountsListener, null, false);
+    }
+
+    private void removeAccountsWatch() {
+        if (mAccountsListener != null) {
+            mAccountManager.removeOnAccountsUpdatedListener(mAccountsListener);
+            mAccountsListener = null;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6ba8514..a6189d2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -632,8 +632,8 @@
     static final String EXTRA_DESCRIPTION = "android.intent.extra.DESCRIPTION";
     static final String EXTRA_BUGREPORT_TYPE = "android.intent.extra.BUGREPORT_TYPE";
     static final String EXTRA_BUGREPORT_NONCE = "android.intent.extra.BUGREPORT_NONCE";
-    static final String EXTRA_EXTRA_ATTACHMENT_URI =
-            "android.intent.extra.EXTRA_ATTACHMENT_URI";
+    static final String EXTRA_EXTRA_ATTACHMENT_URIS =
+            "android.intent.extra.EXTRA_ATTACHMENT_URIS";
 
     /**
      * The maximum number of bytes that {@link #setProcessStateSummary} accepts.
@@ -7660,7 +7660,7 @@
      */
     public void requestBugReportWithDescription(@Nullable String shareTitle,
             @Nullable String shareDescription, int bugreportType, long nonce,
-            @Nullable Uri extraAttachment) {
+            @Nullable List<Uri> extraAttachments) {
         String type = null;
         switch (bugreportType) {
             case BugreportParams.BUGREPORT_MODE_FULL:
@@ -7715,8 +7715,9 @@
         triggerShellBugreport.setPackage(SHELL_APP_PACKAGE);
         triggerShellBugreport.putExtra(EXTRA_BUGREPORT_TYPE, bugreportType);
         triggerShellBugreport.putExtra(EXTRA_BUGREPORT_NONCE, nonce);
-        if (extraAttachment != null) {
-            triggerShellBugreport.putExtra(EXTRA_EXTRA_ATTACHMENT_URI, extraAttachment);
+        if (extraAttachments != null && !extraAttachments.isEmpty()) {
+            triggerShellBugreport.putParcelableArrayListExtra(EXTRA_EXTRA_ATTACHMENT_URIS,
+                    new ArrayList(extraAttachments));
             triggerShellBugreport.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
         }
         triggerShellBugreport.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
@@ -7775,9 +7776,9 @@
      * Takes an interactive bugreport with a progress notification. Also attaches given file uri.
      */
     @Override
-    public void requestBugReportWithExtraAttachment(@NonNull Uri extraAttachment) {
+    public void requestBugReportWithExtraAttachments(@NonNull List<Uri> extraAttachments) {
         requestBugReportWithDescription(null, null, BugreportParams.BUGREPORT_MODE_INTERACTIVE, 0L,
-                extraAttachment);
+                extraAttachments);
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 2f4e8bb..7afcb13 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -176,6 +176,7 @@
         "core_libraries",
         "crumpet",
         "dck_framework",
+        "desktop_stats",
         "devoptions_settings",
         "game",
         "gpu",
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 78a1fa7..bfef685 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -68,10 +68,11 @@
 import static com.android.media.audio.Flags.disablePrescaleAbsoluteVolume;
 import static com.android.media.audio.Flags.equalScoLeaVcIndexRange;
 import static com.android.media.audio.Flags.replaceStreamBtSco;
-import static com.android.media.audio.Flags.ringerModeAffectsAlarm;
 import static com.android.media.audio.Flags.ringMyCar;
+import static com.android.media.audio.Flags.ringerModeAffectsAlarm;
 import static com.android.media.audio.Flags.setStreamVolumeOrder;
 import static com.android.media.audio.Flags.vgsVssSyncMuteOrder;
+import static com.android.media.flags.Flags.enableAudioInputDeviceRoutingAndVolumeControl;
 import static com.android.server.audio.SoundDoseHelper.ACTION_CHECK_MUSIC_ACTIVE;
 import static com.android.server.utils.EventLogger.Event.ALOGE;
 import static com.android.server.utils.EventLogger.Event.ALOGI;
@@ -491,6 +492,10 @@
     private static final int MSG_INIT_SPATIALIZER = 102;
     private static final int MSG_INIT_ADI_DEVICE_STATES = 103;
 
+    private static final int MSG_INIT_INPUT_GAINS = 104;
+    private static final int MSG_SET_INPUT_GAIN_INDEX = 105;
+    private static final int MSG_PERSIST_INPUT_GAIN_INDEX = 106;
+
     // end of messages handled under wakelock
 
     // retry delay in case of failure to indicate system ready to AudioFlinger
@@ -512,6 +517,11 @@
      **/
     private SparseArray<VolumeStreamState> mStreamStates;
 
+    /**
+     * @see InputDeviceVolumeHelper
+     */
+    private InputDeviceVolumeHelper mInputDeviceVolumeHelper;
+
     /*package*/ int getVssVolumeForDevice(int stream, int device) {
         final VolumeStreamState streamState = mStreamStates.get(stream);
         return streamState != null ? streamState.getIndex(device) : -1;
@@ -1501,6 +1511,15 @@
                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER,
                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
+        if (enableAudioInputDeviceRoutingAndVolumeControl()) {
+            queueMsgUnderWakeLock(
+                    mAudioHandler,
+                    MSG_INIT_INPUT_GAINS,
+                    0 /* arg1 */,
+                    0 /* arg2 */,
+                    null /* obj */,
+                    0 /* delay */);
+        }
 
         mDisplayManager = context.getSystemService(DisplayManager.class);
 
@@ -1594,6 +1613,16 @@
         }
     }
 
+    /** Called by handling of MSG_INIT_INPUT_GAINS */
+    private void onInitInputGains() {
+        mInputDeviceVolumeHelper =
+                new InputDeviceVolumeHelper(
+                        mSettings,
+                        mContentResolver,
+                        mSettingsLock,
+                        System.INPUT_GAIN_INDEX_SETTINGS);
+    }
+
     private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener =
             new SubscriptionManager.OnSubscriptionsChangedListener() {
                 @Override
@@ -5742,6 +5771,90 @@
                 : aliasStreamType == sStreamVolumeAlias.get(AudioSystem.STREAM_SYSTEM);
     }
 
+    /**
+     * @see AudioDeviceVolumeManager#setInputGainIndex(AudioDeviceAttributes, int)
+     */
+    @Override
+    @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public void setInputGainIndex(@NonNull AudioDeviceAttributes ada, int index) {
+        super.setInputGainIndex_enforcePermission();
+
+        if (mInputDeviceVolumeHelper.setInputGainIndex(ada, index)) {
+            // Post message to set system volume (it in turn will post a message
+            // to persist).
+            sendMsg(
+                    mAudioHandler,
+                    MSG_SET_INPUT_GAIN_INDEX,
+                    SENDMSG_QUEUE,
+                    /*arg1*/ index,
+                    /*arg2*/ 0,
+                    /*obj*/ ada,
+                    /*delay*/ 0);
+        }
+    }
+
+    private void setInputGainIndexInt(@NonNull AudioDeviceAttributes ada, int index) {
+        // TODO(b/364923030): call AudioSystem to apply input gain in native layer.
+
+        // Post a persist input gain msg.
+        sendMsg(
+                mAudioHandler,
+                MSG_PERSIST_INPUT_GAIN_INDEX,
+                SENDMSG_QUEUE,
+                /*arg1*/ index,
+                /*arg2*/ 0,
+                /*obj*/ ada,
+                PERSIST_DELAY);
+    }
+
+    private void persistInputGainIndex(@NonNull AudioDeviceAttributes ada, int index) {
+        mInputDeviceVolumeHelper.persistInputGainIndex(ada, index);
+    }
+
+    /**
+     * @see AudioDeviceVolumeManager#getInputGainIndex(AudioDeviceAttributes)
+     */
+    @Override
+    @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public int getInputGainIndex(@NonNull AudioDeviceAttributes ada) {
+        super.getInputGainIndex_enforcePermission();
+
+        return mInputDeviceVolumeHelper.getInputGainIndex(ada);
+    }
+
+    /**
+     * @see AudioDeviceVolumeManager#getMaxInputGainIndex()
+     */
+    @Override
+    @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public int getMaxInputGainIndex() {
+        super.getMaxInputGainIndex_enforcePermission();
+
+        return mInputDeviceVolumeHelper.getMaxInputGainIndex();
+    }
+
+    /**
+     * @see AudioDeviceVolumeManager#getMinInputGainIndex()
+     */
+    @Override
+    @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public int getMinInputGainIndex() {
+        super.getMinInputGainIndex_enforcePermission();
+
+        return mInputDeviceVolumeHelper.getMinInputGainIndex();
+    }
+
+    /**
+     * @see AudioDeviceVolumeManager#isInputGainFixed(AudioDeviceAttributes)
+     */
+    @Override
+    @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public boolean isInputGainFixed(@NonNull AudioDeviceAttributes ada) {
+        super.isInputGainFixed_enforcePermission();
+
+        return mInputDeviceVolumeHelper.isInputGainFixed(ada);
+    }
+
     /** @see AudioManager#setMicrophoneMute(boolean) */
     @Override
     public void setMicrophoneMute(boolean on, String callingPackage, int userId,
@@ -10077,6 +10190,14 @@
                     vgs.persistVolumeGroup(msg.arg1);
                     break;
 
+                case MSG_SET_INPUT_GAIN_INDEX:
+                    setInputGainIndexInt((AudioDeviceAttributes) msg.obj, msg.arg1);
+                    break;
+
+                case MSG_PERSIST_INPUT_GAIN_INDEX:
+                    persistInputGainIndex((AudioDeviceAttributes) msg.obj, msg.arg1);
+                    break;
+
                 case MSG_PERSIST_RINGER_MODE:
                     // note that the value persisted is the current ringer mode, not the
                     // value of ringer mode as of the time the request was made to persist
@@ -10147,6 +10268,11 @@
                     mAudioEventWakeLock.release();
                     break;
 
+                case MSG_INIT_INPUT_GAINS:
+                    onInitInputGains();
+                    mAudioEventWakeLock.release();
+                    break;
+
                 case MSG_INIT_ADI_DEVICE_STATES:
                     onInitAdiDeviceStates();
                     mAudioEventWakeLock.release();
diff --git a/services/core/java/com/android/server/audio/InputDeviceVolumeHelper.java b/services/core/java/com/android/server/audio/InputDeviceVolumeHelper.java
new file mode 100644
index 0000000..d83dca6
--- /dev/null
+++ b/services/core/java/com/android/server/audio/InputDeviceVolumeHelper.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2014 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.audio;
+
+import static android.media.AudioManager.GET_DEVICES_INPUTS;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ContentResolver;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.AudioSystem;
+import android.os.UserHandle;
+import android.util.IntArray;
+import android.util.SparseIntArray;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/** Maintains the current state of input gains. */
+/*package*/ class InputDeviceVolumeHelper {
+    private static final String TAG = "InputDeviceVolumeHelper";
+
+    // TODO(b/364923030): retrieve these constants from AudioPolicyManager.
+    private final int INDEX_MIN = 0;
+    private final int INDEX_MAX = 100;
+    private final int INDEX_DEFAULT = 50;
+
+    private final SettingsAdapter mSettings;
+    private final ContentResolver mContentResolver;
+    private final Object mSettingsLock;
+    private final String mInputGainIndexSettingsName;
+
+    // A map between device internal type (e.g. AudioSystem.DEVICE_IN_BUILTIN_MIC) to its input gain
+    // index.
+    private final SparseIntArray mInputGainIndexMap;
+    private final Set<Integer> mSupportedDeviceTypes;
+
+    InputDeviceVolumeHelper(
+            SettingsAdapter settings,
+            ContentResolver contentResolver,
+            Object settingsLock,
+            String settingsName) {
+        mSettings = settings;
+        mContentResolver = contentResolver;
+        mSettingsLock = settingsLock;
+        mInputGainIndexSettingsName = settingsName;
+
+        IntArray internalDeviceTypes = new IntArray();
+        int status = AudioSystem.getSupportedDeviceTypes(GET_DEVICES_INPUTS, internalDeviceTypes);
+        mInputGainIndexMap =
+                new SparseIntArray(
+                        status == AudioManager.SUCCESS
+                                ? internalDeviceTypes.size()
+                                : AudioSystem.DEVICE_IN_ALL_SET.size());
+
+        if (status == AudioManager.SUCCESS) {
+            Set<Integer> supportedDeviceTypes = new HashSet<>();
+            for (int i = 0; i < internalDeviceTypes.size(); i++) {
+                supportedDeviceTypes.add(internalDeviceTypes.get(i));
+            }
+            mSupportedDeviceTypes = supportedDeviceTypes;
+        } else {
+            mSupportedDeviceTypes = AudioSystem.DEVICE_IN_ALL_SET;
+        }
+
+        readSettings();
+    }
+
+    public void readSettings() {
+        synchronized (InputDeviceVolumeHelper.class) {
+            for (int inputDeviceType : mSupportedDeviceTypes) {
+                // Retrieve current input gain for device. If no input gain stored for current
+                // device, use default input gain.
+                int index;
+                if (!hasValidSettingsName()) {
+                    index = INDEX_DEFAULT;
+                } else {
+                    String name = getSettingNameForDevice(inputDeviceType);
+                    index =
+                            mSettings.getSystemIntForUser(
+                                    mContentResolver, name, INDEX_DEFAULT, UserHandle.USER_CURRENT);
+                }
+
+                mInputGainIndexMap.put(inputDeviceType, getValidIndex(index));
+            }
+        }
+    }
+
+    public boolean hasValidSettingsName() {
+        return mInputGainIndexSettingsName != null && !mInputGainIndexSettingsName.isEmpty();
+    }
+
+    public @Nullable String getSettingNameForDevice(int inputDeviceType) {
+        if (!hasValidSettingsName()) {
+            return null;
+        }
+        final String suffix = AudioSystem.getInputDeviceName(inputDeviceType);
+        if (suffix.isEmpty()) {
+            return mInputGainIndexSettingsName;
+        }
+        return mInputGainIndexSettingsName + "_" + suffix;
+    }
+
+    private int getValidIndex(int index) {
+        if (index < INDEX_MIN) {
+            return INDEX_MIN;
+        }
+        if (index > INDEX_MAX) {
+            return INDEX_MAX;
+        }
+        return index;
+    }
+
+    public int getInputGainIndex(@NonNull AudioDeviceAttributes ada) {
+        int inputDeviceType = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice(ada.getType());
+        ensureValidInputDeviceType(inputDeviceType);
+
+        synchronized (InputDeviceVolumeHelper.class) {
+            return mInputGainIndexMap.get(inputDeviceType, INDEX_DEFAULT);
+        }
+    }
+
+    public int getMaxInputGainIndex() {
+        return INDEX_MAX;
+    }
+
+    public int getMinInputGainIndex() {
+        return INDEX_MIN;
+    }
+
+    public boolean isInputGainFixed(@NonNull AudioDeviceAttributes ada) {
+        int inputDeviceType = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice(ada.getType());
+        ensureValidInputDeviceType(inputDeviceType);
+
+        // For simplicity, all devices have non fixed input gain. This might change
+        // when more input devices are supported and some do not support input gain control.
+        return false;
+    }
+
+    public boolean setInputGainIndex(@NonNull AudioDeviceAttributes ada, int index) {
+        int inputDeviceType = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice(ada.getType());
+        ensureValidInputDeviceType(inputDeviceType);
+
+        int oldIndex;
+        synchronized (mSettingsLock) {
+            synchronized (InputDeviceVolumeHelper.class) {
+                oldIndex = getInputGainIndex(ada);
+                index = getValidIndex(index);
+
+                if (oldIndex == index) {
+                    return false;
+                }
+
+                mInputGainIndexMap.put(inputDeviceType, index);
+                return true;
+            }
+        }
+    }
+
+    public void persistInputGainIndex(@NonNull AudioDeviceAttributes ada, int index) {
+        int inputDeviceType = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice(ada.getType());
+        ensureValidInputDeviceType(inputDeviceType);
+
+        if (hasValidSettingsName()) {
+            mSettings.putSystemIntForUser(
+                    mContentResolver,
+                    getSettingNameForDevice(inputDeviceType),
+                    index,
+                    UserHandle.USER_CURRENT);
+        }
+    }
+
+    public boolean isValidInputDeviceType(int inputDeviceType) {
+        return mSupportedDeviceTypes.contains(inputDeviceType);
+    }
+
+    private void ensureValidInputDeviceType(int inputDeviceType) {
+        if (!isValidInputDeviceType(inputDeviceType)) {
+            throw new IllegalArgumentException("Bad input device type " + inputDeviceType);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 7740411..448c42b7 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -82,7 +82,8 @@
     @IntDef(prefix = { "AUTO_BRIGHTNESS_MODE_" }, value = {
             AUTO_BRIGHTNESS_MODE_DEFAULT,
             AUTO_BRIGHTNESS_MODE_IDLE,
-            AUTO_BRIGHTNESS_MODE_DOZE
+            AUTO_BRIGHTNESS_MODE_DOZE,
+            AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface AutomaticBrightnessMode{}
@@ -90,6 +91,7 @@
     public static final int AUTO_BRIGHTNESS_MODE_DEFAULT = 0;
     public static final int AUTO_BRIGHTNESS_MODE_IDLE = 1;
     public static final int AUTO_BRIGHTNESS_MODE_DOZE = 2;
+    public static final int AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR = 3;
     public static final int AUTO_BRIGHTNESS_MODE_MAX = AUTO_BRIGHTNESS_MODE_DOZE;
 
     // How long the current sensor reading is assumed to be valid beyond the current time.
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index 6a019f3..570d5d0 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -18,6 +18,7 @@
 
 import static android.text.TextUtils.formatSimple;
 
+import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE;
@@ -114,7 +115,7 @@
                 luxLevels = getLuxLevels(context.getResources().getIntArray(
                         com.android.internal.R.array.config_autoBrightnessLevelsIdle));
             }
-            case AUTO_BRIGHTNESS_MODE_DOZE -> {
+            case AUTO_BRIGHTNESS_MODE_DOZE, AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR -> {
                 luxLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(mode, preset);
                 brightnessLevels =
                         displayDeviceConfig.getAutoBrightnessBrighteningLevels(mode, preset);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 5b61f00..5c8430b 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -19,6 +19,7 @@
 import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
 import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_OFF;
 
+import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE;
@@ -1086,6 +1087,16 @@
             brightnessMappers.put(AUTO_BRIGHTNESS_MODE_DOZE, dozeModeBrightnessMapper);
         }
 
+        if (mFlags.areAutoBrightnessModesEnabled()
+                && mFlags.isAutoBrightnessModeBedtimeWearEnabled()) {
+            BrightnessMappingStrategy bedtimeBrightnessMapper =
+                    BrightnessMappingStrategy.create(context, mDisplayDeviceConfig,
+                            AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR, mDisplayWhiteBalanceController);
+            if (bedtimeBrightnessMapper != null) {
+                brightnessMappers.put(AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR, bedtimeBrightnessMapper);
+            }
+        }
+
         float userLux = BrightnessMappingStrategy.INVALID_LUX;
         float userNits = BrightnessMappingStrategy.INVALID_NITS;
         if (mAutomaticBrightnessController != null) {
diff --git a/services/core/java/com/android/server/display/config/DisplayBrightnessMappingConfig.java b/services/core/java/com/android/server/display/config/DisplayBrightnessMappingConfig.java
index e0bdda5..458438c 100644
--- a/services/core/java/com/android/server/display/config/DisplayBrightnessMappingConfig.java
+++ b/services/core/java/com/android/server/display/config/DisplayBrightnessMappingConfig.java
@@ -16,6 +16,7 @@
 
 package com.android.server.display.config;
 
+import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE;
@@ -247,6 +248,9 @@
             case AUTO_BRIGHTNESS_MODE_DOZE -> {
                 return AutoBrightnessModeName.doze.getRawName();
             }
+            case AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR -> {
+                return AutoBrightnessModeName.bedtime_wear.getRawName();
+            }
             default -> throw new IllegalArgumentException("Unknown auto-brightness mode: " + mode);
         }
     }
diff --git a/services/core/java/com/android/server/incident/PendingReports.java b/services/core/java/com/android/server/incident/PendingReports.java
index adcda0a..35b3673 100644
--- a/services/core/java/com/android/server/incident/PendingReports.java
+++ b/services/core/java/com/android/server/incident/PendingReports.java
@@ -304,16 +304,16 @@
             denyReportBeforeAddingRec(listener, callingPackage);
             return;
         }
+        AttributionSource attributionSource =
+                    new AttributionSource.Builder(callingUid)
+                            .setPackageName(callingPackage)
+                            .build();
 
         // Only with userdebug/eng build: it could check capture consentless bugreport permission
         // and approve the report when it's granted.
         boolean captureConsentlessBugreportOnUserdebugBuildGranted = false;
         if ((Build.IS_USERDEBUG || Build.IS_ENG)
                 && (flags & IncidentManager.FLAG_ALLOW_CONSENTLESS_BUGREPORT) != 0) {
-            AttributionSource attributionSource =
-                    new AttributionSource.Builder(callingUid)
-                            .setPackageName(callingPackage)
-                            .build();
             captureConsentlessBugreportOnUserdebugBuildGranted =
                     mPermissionManager.checkPermissionForDataDelivery(
                             Manifest.permission.CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD,
@@ -321,12 +321,32 @@
                             /* message= */ null)
                             == PERMISSION_GRANTED;
         }
-        if (captureConsentlessBugreportOnUserdebugBuildGranted) {
+
+        // Allow system apps to skip the consent dialog and use their in-built consent mechanism
+        // instead.
+        boolean captureConsentlessBugreportDelegatedConsentGranted = false;
+        if ((flags & IncidentManager.FLAG_ALLOW_CONSENTLESS_BUGREPORT) != 0) {
+            captureConsentlessBugreportDelegatedConsentGranted =
+                    mPermissionManager.checkPermissionForDataDelivery(
+                                    Manifest.permission
+                                            .CAPTURE_CONSENTLESS_BUGREPORT_DELEGATED_CONSENT,
+                                    attributionSource,
+                                    /* message= */ null)
+                            == PERMISSION_GRANTED;
+        }
+
+        if (captureConsentlessBugreportOnUserdebugBuildGranted
+                || captureConsentlessBugreportDelegatedConsentGranted) {
             try {
                 PendingReportRec rec =
                         new PendingReportRec(
                                 callingPackage, receiverClass, reportId, flags, listener);
-                Log.d(TAG, "approving consentless report: " + rec.getUri());
+                if (captureConsentlessBugreportOnUserdebugBuildGranted) {
+                    Log.d(TAG, "approving consentless report: " + rec.getUri());
+                }
+                if (captureConsentlessBugreportDelegatedConsentGranted) {
+                    Log.d(TAG, "delegating consent for report: " + rec.getUri());
+                }
                 listener.onReportApproved();
                 return;
             } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/incident/TEST_MAPPING b/services/core/java/com/android/server/incident/TEST_MAPPING
new file mode 100644
index 0000000..4f789db
--- /dev/null
+++ b/services/core/java/com/android/server/incident/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "postsubmit": [
+    {
+      "name": "CtsRootBugreportTestCases"
+    },
+    {
+      "name": "BugreportManagerTestCases"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/input/InputManagerInternal.java b/services/core/java/com/android/server/input/InputManagerInternal.java
index c888eef..e40d855 100644
--- a/services/core/java/com/android/server/input/InputManagerInternal.java
+++ b/services/core/java/com/android/server/input/InputManagerInternal.java
@@ -270,4 +270,18 @@
      * @param scaleFactor the new scale factor to be applied for pointer icons.
      */
     public abstract void setAccessibilityPointerIconScaleFactor(int displayId, float scaleFactor);
+
+    /**
+     * Set whether the given input device can wake up the kernel from sleep
+     * when it generates input events. By default, usually only internal (built-in)
+     * input devices can wake the kernel from sleep. For an external input device
+     * that supports remote wakeup to be able to wake the kernel, this must be called
+     * after each time the device is connected/added.
+     *
+     * @param deviceId the device ID of the input device.
+     * @param enabled When true, device will be configured to wake up kernel.
+     *
+     * @return true if setting power wakeup was successful.
+     */
+    public abstract boolean setKernelWakeEnabled(int deviceId, boolean enabled);
 }
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 98e5319..bea520f 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -3511,6 +3511,11 @@
         public void setAccessibilityPointerIconScaleFactor(int displayId, float scaleFactor) {
             InputManagerService.this.setAccessibilityPointerIconScaleFactor(displayId, scaleFactor);
         }
+
+        @Override
+        public boolean setKernelWakeEnabled(int deviceId, boolean enabled) {
+            return mNative.setKernelWakeEnabled(deviceId, enabled);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
index 2f5236f..bd1625e 100644
--- a/services/core/java/com/android/server/input/KeyGestureController.java
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -20,6 +20,7 @@
 import static android.content.pm.PackageManager.FEATURE_WATCH;
 import static android.view.WindowManagerPolicyConstants.FLAG_INTERACTIVE;
 
+import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
 import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
 import static com.android.hardware.input.Flags.useKeyGestureEventHandlerMultiPressGestures;
 import static com.android.server.flags.Flags.newBugreportKeyboardShortcut;
@@ -577,6 +578,17 @@
                             focusedToken, /* flags = */0);
                 }
                 break;
+            case KeyEvent.KEYCODE_T:
+                if (keyboardA11yShortcutControl()) {
+                    if (firstDown && event.isMetaPressed() && event.isAltPressed()) {
+                        return handleKeyGesture(deviceId, new int[]{keyCode},
+                                KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
+                                KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK,
+                                KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId,
+                                focusedToken, /* flags = */0);
+                    }
+                }
+                break;
             case KeyEvent.KEYCODE_DEL:
                 if (newBugreportKeyboardShortcut()) {
                     if (firstDown && mEnableBugReportKeyboardShortcut && event.isMetaPressed()
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index 21e8bcc..283fdea 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -287,6 +287,17 @@
      */
     int getLastUsedInputDeviceId();
 
+    /**
+     * Set whether the given input device can wake up the kernel from sleep
+     * when it generates input events. By default, usually only internal (built-in)
+     * input devices can wake the kernel from sleep. For an external input device
+     * that supports remote wakeup to be able to wake the kernel, this must be called
+     * after each time the device is connected/added.
+     *
+     * Returns true if setting power wakeup was successful.
+     */
+    boolean setKernelWakeEnabled(int deviceId, boolean enabled);
+
     /** The native implementation of InputManagerService methods. */
     class NativeImpl implements NativeInputManagerService {
         /** Pointer to native input manager service object, used by native code. */
@@ -573,5 +584,8 @@
 
         @Override
         public native int getLastUsedInputDeviceId();
+
+        @Override
+        public native boolean setKernelWakeEnabled(int deviceId, boolean enabled);
     }
 }
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index 509fa3e..bb4ae96 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -74,7 +74,6 @@
     private final Context mContext;
     private final Handler mHandler;
     private final PackageManagerInternal mPackageManagerInternal;
-    private final IntegrityFileManager mIntegrityFileManager;
 
     /** Create an instance of {@link AppIntegrityManagerServiceImpl}. */
     public static AppIntegrityManagerServiceImpl create(Context context) {
@@ -84,7 +83,6 @@
         return new AppIntegrityManagerServiceImpl(
                 context,
                 LocalServices.getService(PackageManagerInternal.class),
-                IntegrityFileManager.getInstance(),
                 handlerThread.getThreadHandler());
     }
 
@@ -92,11 +90,9 @@
     AppIntegrityManagerServiceImpl(
             Context context,
             PackageManagerInternal packageManagerInternal,
-            IntegrityFileManager integrityFileManager,
             Handler handler) {
         mContext = context;
         mPackageManagerInternal = packageManagerInternal;
-        mIntegrityFileManager = integrityFileManager;
         mHandler = handler;
 
         IntentFilter integrityVerificationFilter = new IntentFilter();
@@ -144,39 +140,23 @@
     @Override
     @BinderThread
     public String getCurrentRuleSetVersion() {
-        getCallerPackageNameOrThrow(Binder.getCallingUid());
-
-        RuleMetadata ruleMetadata = mIntegrityFileManager.readMetadata();
-        return (ruleMetadata != null && ruleMetadata.getVersion() != null)
-                ? ruleMetadata.getVersion()
-                : "";
+        return "";
     }
 
     @Override
     @BinderThread
     public String getCurrentRuleSetProvider() {
-        getCallerPackageNameOrThrow(Binder.getCallingUid());
-
-        RuleMetadata ruleMetadata = mIntegrityFileManager.readMetadata();
-        return (ruleMetadata != null && ruleMetadata.getRuleProvider() != null)
-                ? ruleMetadata.getRuleProvider()
-                : "";
+        return "";
     }
 
     @Override
     public ParceledListSlice<Rule> getCurrentRules() {
-        List<Rule> rules = Collections.emptyList();
-        try {
-            rules = mIntegrityFileManager.readRules(/* appInstallMetadata= */ null);
-        } catch (Exception e) {
-            Slog.e(TAG, "Error getting current rules", e);
-        }
-        return new ParceledListSlice<>(rules);
+        return new ParceledListSlice<>(Collections.emptyList());
     }
 
     @Override
     public List<String> getWhitelistedRuleProviders() {
-        return getAllowedRuleProviderSystemApps();
+        return Collections.emptyList();
     }
 
     private void handleIntegrityVerification(Intent intent) {
@@ -184,75 +164,4 @@
         mPackageManagerInternal.setIntegrityVerificationResult(
                 verificationId, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
     }
-
-    private String getCallerPackageNameOrThrow(int callingUid) {
-        String callerPackageName = getCallingRulePusherPackageName(callingUid);
-        if (callerPackageName == null) {
-            throw new SecurityException(
-                    "Only system packages specified in config_integrityRuleProviderPackages are "
-                            + "allowed to call this method.");
-        }
-        return callerPackageName;
-    }
-
-    private String getCallingRulePusherPackageName(int callingUid) {
-        // Obtain the system apps that are allowlisted in config_integrityRuleProviderPackages.
-        List<String> allowedRuleProviders = getAllowedRuleProviderSystemApps();
-        if (DEBUG_INTEGRITY_COMPONENT) {
-            Slog.i(
-                    TAG,
-                    String.format(
-                            "Rule provider system app list contains: %s", allowedRuleProviders));
-        }
-
-        // Identify the package names in the caller list.
-        List<String> callingPackageNames = getPackageListForUid(callingUid);
-
-        // Find the intersection between the allowed and calling packages. Ideally, we will have
-        // at most one package name here. But if we have more, it is fine.
-        List<String> allowedCallingPackages = new ArrayList<>();
-        for (String packageName : callingPackageNames) {
-            if (allowedRuleProviders.contains(packageName)) {
-                allowedCallingPackages.add(packageName);
-            }
-        }
-
-        return allowedCallingPackages.isEmpty() ? null : allowedCallingPackages.get(0);
-    }
-
-    private List<String> getAllowedRuleProviderSystemApps() {
-        List<String> integrityRuleProviders =
-                Arrays.asList(
-                        mContext.getResources()
-                                .getStringArray(R.array.config_integrityRuleProviderPackages));
-
-        // Filter out the rule provider packages that are not system apps.
-        List<String> systemAppRuleProviders = new ArrayList<>();
-        for (String ruleProvider : integrityRuleProviders) {
-            if (isSystemApp(ruleProvider)) {
-                systemAppRuleProviders.add(ruleProvider);
-            }
-        }
-        return systemAppRuleProviders;
-    }
-
-    private boolean isSystemApp(String packageName) {
-        try {
-            PackageInfo existingPackageInfo =
-                    mContext.getPackageManager().getPackageInfo(packageName, /* flags= */ 0);
-            return existingPackageInfo.applicationInfo != null
-                    && existingPackageInfo.applicationInfo.isSystemApp();
-        } catch (PackageManager.NameNotFoundException e) {
-            return false;
-        }
-    }
-
-    private List<String> getPackageListForUid(int uid) {
-        try {
-            return Arrays.asList(mContext.getPackageManager().getPackagesForUid(uid));
-        } catch (NullPointerException e) {
-            Slog.w(TAG, String.format("No packages were found for uid: %d", uid));
-            return List.of();
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/notification/EventConditionProvider.java b/services/core/java/com/android/server/notification/EventConditionProvider.java
index ecc4cf7..308f299 100644
--- a/services/core/java/com/android/server/notification/EventConditionProvider.java
+++ b/services/core/java/com/android/server/notification/EventConditionProvider.java
@@ -16,7 +16,6 @@
 
 package com.android.server.notification;
 
-import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
@@ -68,7 +67,7 @@
     private final Handler mWorker;
     private final HandlerThread mThread;
 
-    @Nullable private UserHandle mCurrentUser;
+    private UserHandle mCurrentUser = UserHandle.SYSTEM;
     private boolean mConnected;
     private boolean mRegistered;
     private boolean mBootComplete;  // don't hammer the calendar provider until boot completes.
@@ -119,18 +118,19 @@
             @Override
             public void onReceive(Context context, Intent intent) {
                 if (android.app.Flags.modesHsum()) {
-                    if (mCurrentUser != null) {
-                        // Possibly the intent signals a profile added on a different user, but it
-                        // doesn't matter (except for a bit of wasted work here). We will reload
-                        // trackers for that user when we switch.
-                        reloadTrackers(mCurrentUser);
-                    }
+                    // Possibly the intent signals a profile added on a different user, but it
+                    // doesn't matter (except for a bit of wasted work here). We will reload
+                    // trackers for that user when we switch.
+                    reloadTrackers(mCurrentUser);
                 } else {
                     reloadTrackers();
                 }
             }
         }, filter);
-        if (!android.app.Flags.modesHsum()) {
+
+        if (android.app.Flags.modesHsum()) {
+            reloadTrackers(UserHandle.SYSTEM);
+        } else {
             reloadTrackers();
         }
     }
@@ -138,8 +138,10 @@
     @Override
     public void onUserSwitched(UserHandle user) {
         if (DEBUG) Slog.d(TAG, "onUserSwitched: " + user);
-        mCurrentUser = user;
-        reloadTrackers(user);
+        if (mCurrentUser.getIdentifier() != user.getIdentifier()) {
+            mCurrentUser = user;
+            reloadTrackers(user);
+        }
     }
 
     @Override
@@ -274,12 +276,23 @@
                     final int userId = EventInfo.resolveUserId(event.userId);
                     final CalendarTracker tracker = mTrackers.get(userId);
                     if (tracker == null) {
-                        Slog.w(TAG, "No calendar tracker found for user " + userId);
+                        Slog.w(TAG,
+                                "No calendar tracker found for user " + userId + " and calendar = "
+                                        + event.calName);
                         conditionsToNotify.add(createCondition(conditionId, Condition.STATE_FALSE));
                         continue;
                     }
                     result = tracker.checkEvent(event, now);
                 }
+
+                if (result == null) {
+                    Slog.e(TAG, "No CheckEventResult for userId=" + event.userId + ", calId="
+                            + event.calendarId + ", calName=" + event.calName
+                            + "; trackers count is " + mTrackers.size());
+                    conditionsToNotify.add(createCondition(conditionId, Condition.STATE_FALSE));
+                    continue;
+                }
+
                 if (result.recheckAt != 0
                         && (reevaluateAt == 0 || result.recheckAt < reevaluateAt)) {
                     reevaluateAt = result.recheckAt;
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index c9edc410..964a5d0 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -440,6 +440,10 @@
             PackagePreferences r) {
         try {
             String id = parser.getAttributeValue(null, ATT_ID);
+            if (!notificationClassification() && SYSTEM_RESERVED_IDS.contains(id)) {
+                // delete bundle channels if flag is rolled back
+                return;
+            }
             String channelName = parser.getAttributeValue(null, ATT_NAME);
             int channelImportance = parser.getAttributeInt(
                     null, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
diff --git a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
index 24b090c..734c61b 100644
--- a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
+++ b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
@@ -42,6 +42,7 @@
 import com.android.server.pm.PackageManagerService;
 
 import java.io.PrintWriter;
+import java.time.Clock;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
@@ -62,6 +63,7 @@
     private static final String SCP_SETTING = "snoozed_schedule_condition_provider";
 
     private final Context mContext = this;
+    private final Clock mClock;
     private final ArrayMap<Uri, ScheduleCalendar> mSubscriptions = new ArrayMap<>();
     @GuardedBy("mSnoozedForAlarm")
     private final ArraySet<Uri> mSnoozedForAlarm = new ArraySet<>();
@@ -72,7 +74,13 @@
     private long mNextAlarmTime;
 
     public ScheduleConditionProvider() {
+        this(Clock.systemUTC());
+    }
+
+    @VisibleForTesting
+    ScheduleConditionProvider(Clock clock) {
         if (DEBUG) Slog.d(TAG, "new " + SIMPLE_NAME + "()");
+        mClock = clock;
     }
 
     @Override
@@ -86,7 +94,7 @@
         pw.print("      mConnected="); pw.println(mConnected);
         pw.print("      mRegistered="); pw.println(mRegistered);
         pw.println("      mSubscriptions=");
-        final long now = System.currentTimeMillis();
+        final long now = mClock.millis();
         synchronized (mSubscriptions) {
             for (Uri conditionId : mSubscriptions.keySet()) {
                 pw.print("        ");
@@ -117,7 +125,9 @@
 
     @Override
     public void onUserSwitched(UserHandle user) {
-        // Nothing to do because time-based schedules are not tied to any user data.
+        // Nothing to do here because evaluateSubscriptions() is called for the new configuration
+        // when users switch, and that will reevaluate the next alarm, which is the only piece that
+        // is user-dependent.
     }
 
     @Override
@@ -151,12 +161,9 @@
     }
 
     private void evaluateSubscriptions() {
-        if (mAlarmManager == null) {
-            mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-        }
-        final long now = System.currentTimeMillis();
+        final long now = mClock.millis();
         mNextAlarmTime = 0;
-        long nextUserAlarmTime = getNextAlarm();
+        long nextUserAlarmTime = getNextAlarmClockAlarm();
         List<Condition> conditionsToNotify = new ArrayList<>();
         synchronized (mSubscriptions) {
             setRegistered(!mSubscriptions.isEmpty());
@@ -232,7 +239,10 @@
                 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
     }
 
-    public long getNextAlarm() {
+    private long getNextAlarmClockAlarm() {
+        if (mAlarmManager == null) {
+            mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+        }
         final AlarmManager.AlarmClockInfo info = mAlarmManager.getNextAlarmClock(
                 ActivityManager.getCurrentUser());
         return info != null ? info.getTriggerTime() : 0;
@@ -252,8 +262,13 @@
             filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
             filter.addAction(ACTION_EVALUATE);
             filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
-            registerReceiver(mReceiver, filter,
-                    Context.RECEIVER_EXPORTED_UNAUDITED);
+            if (android.app.Flags.modesHsum()) {
+                registerReceiverForAllUsers(mReceiver, filter, /* broadcastPermission= */ null,
+                        /* scheduler= */ null);
+            } else {
+                registerReceiver(mReceiver, filter,
+                        Context.RECEIVER_EXPORTED_UNAUDITED);
+            }
         } else {
             unregisterReceiver(mReceiver);
         }
@@ -327,10 +342,18 @@
         }
     }
 
-    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             if (DEBUG) Slog.d(TAG, "onReceive " + intent.getAction());
+            if (android.app.Flags.modesHsum()) {
+                if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(intent.getAction())
+                        && getSendingUserId() != ActivityManager.getCurrentUser()) {
+                    // A different user changed their next alarm.
+                    return;
+                }
+            }
+
             if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
                 synchronized (mSubscriptions) {
                     for (Uri conditionId : mSubscriptions.keySet()) {
@@ -345,4 +368,8 @@
         }
     };
 
+    @VisibleForTesting // otherwise = NONE
+    public ArrayMap<Uri, ScheduleCalendar> getSubscriptions() {
+        return mSubscriptions;
+    }
 }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index ad5c840..0b5b0d2 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -84,6 +84,7 @@
 import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled;
 
 import static com.android.hardware.input.Flags.emojiAndScreenshotKeycodesAvailable;
+import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
 import static com.android.hardware.input.Flags.modifierShortcutDump;
 import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
 import static com.android.hardware.input.Flags.useKeyGestureEventHandlerMultiPressGestures;
@@ -1615,7 +1616,8 @@
             case TRIPLE_PRESS_PRIMARY_NOTHING:
                 break;
             case TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY:
-                mTalkbackShortcutController.toggleTalkback(mCurrentUserId);
+                mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
+                        TalkbackShortcutController.ShortcutSource.GESTURE);
                 if (mTalkbackShortcutController.isTalkBackShortcutGestureEnabled()) {
                     performHapticFeedback(HapticFeedbackConstants.CONFIRM,
                             "Stem primary - Triple Press - Toggle Accessibility");
@@ -3603,6 +3605,17 @@
                     return true;
                 }
                 break;
+            case KeyEvent.KEYCODE_T:
+                if (keyboardA11yShortcutControl()) {
+                    if (firstDown && event.isMetaPressed() && event.isAltPressed()) {
+                        mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
+                                TalkbackShortcutController.ShortcutSource.KEYBOARD);
+                        notifyKeyGestureCompleted(event,
+                                KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK);
+                        return true;
+                    }
+                }
+                break;
             case KeyEvent.KEYCODE_DEL:
                 if (newBugreportKeyboardShortcut()) {
                     if (mEnableBugReportKeyboardShortcut && firstDown
@@ -4034,6 +4047,8 @@
                     case KeyGestureEvent.KEY_GESTURE_TYPE_TV_ACCESSIBILITY_SHORTCUT_CHORD:
                         return mDefaultDisplayPolicy.isAwake() && mAccessibilityShortcutController
                                 .isAccessibilityShortcutAvailable(false);
+                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
+                        return keyboardA11yShortcutControl();
                     default:
                         return false;
                 }
@@ -4251,6 +4266,15 @@
                     mContext.closeSystemDialogs();
                 }
                 return true;
+            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
+                if (keyboardA11yShortcutControl()) {
+                    if (complete) {
+                        mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
+                                TalkbackShortcutController.ShortcutSource.KEYBOARD);
+                    }
+                    return true;
+                }
+                break;
         }
         return false;
     }
diff --git a/services/core/java/com/android/server/policy/TalkbackShortcutController.java b/services/core/java/com/android/server/policy/TalkbackShortcutController.java
index e544ae6..9e16a7d 100644
--- a/services/core/java/com/android/server/policy/TalkbackShortcutController.java
+++ b/services/core/java/com/android/server/policy/TalkbackShortcutController.java
@@ -44,6 +44,11 @@
     private final Context mContext;
     private final PackageManager mPackageManager;
 
+    public enum ShortcutSource {
+        GESTURE,
+        KEYBOARD,
+    }
+
     TalkbackShortcutController(Context context) {
         mContext = context;
         mPackageManager = mContext.getPackageManager();
@@ -55,7 +60,7 @@
      * @return talkback state after toggle. {@code true} if talkback is enabled, {@code false} if
      * talkback is disabled
      */
-    boolean toggleTalkback(int userId) {
+    boolean toggleTalkback(int userId, ShortcutSource source) {
         final Set<ComponentName> enabledServices =
                 AccessibilityUtils.getEnabledServicesFromSettings(mContext, userId);
         ComponentName componentName = getTalkbackComponent();
@@ -65,13 +70,13 @@
 
         boolean isTalkbackAlreadyEnabled = enabledServices.contains(componentName);
 
-        if (isTalkBackShortcutGestureEnabled()) {
+        if (source == ShortcutSource.KEYBOARD || isTalkBackShortcutGestureEnabled()) {
             isTalkbackAlreadyEnabled = !isTalkbackAlreadyEnabled;
             AccessibilityUtils.setAccessibilityServiceState(mContext, componentName,
-                    isTalkbackAlreadyEnabled);
+                    isTalkbackAlreadyEnabled, userId);
 
             // log stem triple press telemetry if it's a talkback enabled event.
-            if (isTalkbackAlreadyEnabled) {
+            if (source == ShortcutSource.GESTURE && isTalkbackAlreadyEnabled) {
                 logStemTriplePressAccessibilityTelemetry(componentName);
             }
         }
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index dc6b164..78bc06c 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -31,6 +31,7 @@
 import android.hardware.thermal.IThermal;
 import android.hardware.thermal.IThermalChangedCallback;
 import android.hardware.thermal.TemperatureThreshold;
+import android.hardware.thermal.TemperatureType;
 import android.hardware.thermal.ThrottlingSeverity;
 import android.hardware.thermal.V1_0.ThermalStatus;
 import android.hardware.thermal.V1_0.ThermalStatusCode;
@@ -134,6 +135,31 @@
     @VisibleForTesting
     final TemperatureWatcher mTemperatureWatcher = new TemperatureWatcher();
 
+    private final ThermalHalWrapper.WrapperThermalChangedCallback mWrapperCallback =
+            new ThermalHalWrapper.WrapperThermalChangedCallback() {
+                @Override
+                public void onTemperatureChanged(Temperature temperature) {
+                    final long token = Binder.clearCallingIdentity();
+                    try {
+                        ThermalManagerService.this.onTemperatureChanged(temperature, true);
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
+
+                @Override
+                public void onThresholdChanged(TemperatureThreshold threshold) {
+                    final long token = Binder.clearCallingIdentity();
+                    try {
+                        synchronized (mTemperatureWatcher.mSamples) {
+                            mTemperatureWatcher.updateTemperatureThresholdLocked(threshold, true);
+                        }
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
+            };
+
     private final Context mContext;
 
     public ThermalManagerService(Context context) {
@@ -146,7 +172,7 @@
         mContext = context;
         mHalWrapper = halWrapper;
         if (halWrapper != null) {
-            halWrapper.setCallback(this::onTemperatureChangedCallback);
+            halWrapper.setCallback(mWrapperCallback);
         }
         mStatus = Temperature.THROTTLING_NONE;
     }
@@ -171,19 +197,19 @@
             // Connect to HAL and post to listeners.
             boolean halConnected = (mHalWrapper != null);
             if (!halConnected) {
-                mHalWrapper = new ThermalHalAidlWrapper(this::onTemperatureChangedCallback);
+                mHalWrapper = new ThermalHalAidlWrapper(mWrapperCallback);
                 halConnected = mHalWrapper.connectToHal();
             }
             if (!halConnected) {
-                mHalWrapper = new ThermalHal20Wrapper(this::onTemperatureChangedCallback);
+                mHalWrapper = new ThermalHal20Wrapper(mWrapperCallback);
                 halConnected = mHalWrapper.connectToHal();
             }
             if (!halConnected) {
-                mHalWrapper = new ThermalHal11Wrapper(this::onTemperatureChangedCallback);
+                mHalWrapper = new ThermalHal11Wrapper(mWrapperCallback);
                 halConnected = mHalWrapper.connectToHal();
             }
             if (!halConnected) {
-                mHalWrapper = new ThermalHal10Wrapper(this::onTemperatureChangedCallback);
+                mHalWrapper = new ThermalHal10Wrapper(mWrapperCallback);
                 halConnected = mHalWrapper.connectToHal();
             }
             if (!halConnected) {
@@ -200,7 +226,7 @@
                 onTemperatureChanged(temperatures.get(i), false);
             }
             onTemperatureMapChangedLocked();
-            mTemperatureWatcher.updateThresholds();
+            mTemperatureWatcher.getAndUpdateThresholds();
             mHalReady.set(true);
         }
     }
@@ -335,16 +361,6 @@
         }
     }
 
-    /* HwBinder callback **/
-    private void onTemperatureChangedCallback(Temperature temperature) {
-        final long token = Binder.clearCallingIdentity();
-        try {
-            onTemperatureChanged(temperature, true);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
     private void registerStatsCallbacks() {
         final StatsManager statsManager = mContext.getSystemService(StatsManager.class);
         if (statsManager != null) {
@@ -924,19 +940,19 @@
         /** Lock to protect HAL handle. */
         protected final Object mHalLock = new Object();
 
-        @FunctionalInterface
-        interface TemperatureChangedCallback {
-            void onValues(Temperature temperature);
+        interface WrapperThermalChangedCallback {
+            void onTemperatureChanged(Temperature temperature);
+            void onThresholdChanged(TemperatureThreshold threshold);
         }
 
         /** Temperature callback. */
-        protected TemperatureChangedCallback mCallback;
+        protected WrapperThermalChangedCallback mCallback;
 
         /** Cookie for matching the right end point. */
         protected static final int THERMAL_HAL_DEATH_COOKIE = 5612;
 
         @VisibleForTesting
-        protected void setCallback(TemperatureChangedCallback cb) {
+        protected void setCallback(WrapperThermalChangedCallback cb) {
             mCallback = cb;
         }
 
@@ -959,7 +975,7 @@
                 List<Temperature> temperatures = getCurrentTemperatures(false, 0);
                 final int count = temperatures.size();
                 for (int i = 0; i < count; i++) {
-                    mCallback.onValues(temperatures.get(i));
+                    mCallback.onTemperatureChanged(temperatures.get(i));
                 }
             }
         }
@@ -985,31 +1001,42 @@
         private IThermal mInstance = null;
 
         /** Callback for Thermal HAL AIDL. */
-        private final IThermalChangedCallback mThermalChangedCallback =
+        private final IThermalChangedCallback mThermalCallbackAidl =
                 new IThermalChangedCallback.Stub() {
-                    @Override public void notifyThrottling(
-                            android.hardware.thermal.Temperature temperature)
-                            throws RemoteException {
+                    @Override
+                    public void notifyThrottling(
+                            android.hardware.thermal.Temperature temperature) {
                         Temperature svcTemperature = new Temperature(temperature.value,
                                 temperature.type, temperature.name, temperature.throttlingStatus);
                         final long token = Binder.clearCallingIdentity();
                         try {
-                            mCallback.onValues(svcTemperature);
+                            mCallback.onTemperatureChanged(svcTemperature);
                         } finally {
                             Binder.restoreCallingIdentity(token);
                         }
                     }
 
-            @Override public int getInterfaceVersion() throws RemoteException {
-                return this.VERSION;
-            }
+                    @Override
+                    public void notifyThresholdChanged(TemperatureThreshold threshold) {
+                        if (Flags.allowThermalThresholdsCallback()) {
+                            if (threshold.type == TemperatureType.SKIN) {
+                                mCallback.onThresholdChanged(threshold);
+                            }
+                        }
+                    }
 
-            @Override public String getInterfaceHash() throws RemoteException {
-                return this.HASH;
-            }
-        };
+                    @Override
+                    public int getInterfaceVersion() throws RemoteException {
+                        return this.VERSION;
+                    }
 
-        ThermalHalAidlWrapper(TemperatureChangedCallback callback) {
+                    @Override
+                    public String getInterfaceHash() throws RemoteException {
+                        return this.HASH;
+                    }
+                };
+
+        ThermalHalAidlWrapper(WrapperThermalChangedCallback callback) {
             mCallback = callback;
         }
 
@@ -1153,7 +1180,7 @@
         @VisibleForTesting
         void registerThermalChangedCallback() {
             try {
-                mInstance.registerThermalChangedCallback(mThermalChangedCallback);
+                mInstance.registerThermalChangedCallback(mThermalCallbackAidl);
             } catch (IllegalArgumentException | IllegalStateException e) {
                 Slog.e(TAG, "Couldn't registerThermalChangedCallback due to invalid status",
                         e);
@@ -1185,7 +1212,7 @@
         @GuardedBy("mHalLock")
         private android.hardware.thermal.V1_0.IThermal mThermalHal10 = null;
 
-        ThermalHal10Wrapper(TemperatureChangedCallback callback) {
+        ThermalHal10Wrapper(WrapperThermalChangedCallback callback) {
             mCallback = callback;
         }
 
@@ -1317,14 +1344,14 @@
                                         : Temperature.THROTTLING_NONE);
                         final long token = Binder.clearCallingIdentity();
                         try {
-                            mCallback.onValues(thermalSvcTemp);
+                            mCallback.onTemperatureChanged(thermalSvcTemp);
                         } finally {
                             Binder.restoreCallingIdentity(token);
                         }
                     }
                 };
 
-        ThermalHal11Wrapper(TemperatureChangedCallback callback) {
+        ThermalHal11Wrapper(WrapperThermalChangedCallback callback) {
             mCallback = callback;
         }
 
@@ -1455,14 +1482,14 @@
                                 temperature.throttlingStatus);
                         final long token = Binder.clearCallingIdentity();
                         try {
-                            mCallback.onValues(thermalSvcTemp);
+                            mCallback.onTemperatureChanged(thermalSvcTemp);
                         } finally {
                             Binder.restoreCallingIdentity(token);
                         }
                     }
                 };
 
-        ThermalHal20Wrapper(TemperatureChangedCallback callback) {
+        ThermalHal20Wrapper(WrapperThermalChangedCallback callback) {
             mCallback = callback;
         }
 
@@ -1627,52 +1654,57 @@
         @VisibleForTesting
         long mInactivityThresholdMillis = INACTIVITY_THRESHOLD_MILLIS;
 
-        void updateThresholds() {
+        void getAndUpdateThresholds() {
             List<TemperatureThreshold> thresholds =
                         mHalWrapper.getTemperatureThresholds(true, Temperature.TYPE_SKIN);
             synchronized (mSamples) {
                 if (Flags.allowThermalHeadroomThresholds()) {
                     Arrays.fill(mHeadroomThresholds, Float.NaN);
                 }
-                for (int t = 0; t < thresholds.size(); ++t) {
-                    TemperatureThreshold threshold = thresholds.get(t);
-                    if (threshold.hotThrottlingThresholds.length <= ThrottlingSeverity.SEVERE) {
-                        continue;
-                    }
-                    float severeThreshold =
-                            threshold.hotThrottlingThresholds[ThrottlingSeverity.SEVERE];
-                    if (!Float.isNaN(severeThreshold)) {
-                        mSevereThresholds.put(threshold.name, severeThreshold);
-                        if (Flags.allowThermalHeadroomThresholds()) {
-                            for (int severity = ThrottlingSeverity.LIGHT;
-                                    severity <= ThrottlingSeverity.SHUTDOWN; severity++) {
-                                if (threshold.hotThrottlingThresholds.length > severity) {
-                                    updateHeadroomThreshold(severity,
-                                            threshold.hotThrottlingThresholds[severity],
-                                            severeThreshold);
-                                }
-                            }
-                        }
-                    }
+                for (final TemperatureThreshold threshold : thresholds) {
+                    updateTemperatureThresholdLocked(threshold, false);
                 }
             }
         }
 
         // For an older device with multiple SKIN sensors, we will set a severity's headroom
-        // threshold based on the minimum value of all as a workaround.
-        void updateHeadroomThreshold(int severity, float threshold, float severeThreshold) {
-            if (!Float.isNaN(threshold)) {
-                synchronized (mSamples) {
-                    if (severity == ThrottlingSeverity.SEVERE) {
-                        mHeadroomThresholds[severity] = 1.0f;
-                        return;
+        // threshold based on the minimum value of all as a workaround, unless override.
+        @GuardedBy("mSamples")
+        void updateTemperatureThresholdLocked(TemperatureThreshold threshold, boolean override) {
+            if (threshold.hotThrottlingThresholds.length <= ThrottlingSeverity.SEVERE) {
+                return;
+            }
+            float severeThreshold =
+                    threshold.hotThrottlingThresholds[ThrottlingSeverity.SEVERE];
+            if (Float.isNaN(severeThreshold)) {
+                return;
+            }
+            mSevereThresholds.put(threshold.name, severeThreshold);
+            if (!Flags.allowThermalHeadroomThresholds()) {
+                return;
+            }
+            if (override) {
+                Arrays.fill(mHeadroomThresholds, Float.NaN);
+            }
+            for (int severity = ThrottlingSeverity.LIGHT;
+                    severity <= ThrottlingSeverity.SHUTDOWN; severity++) {
+                if (threshold.hotThrottlingThresholds.length > severity) {
+                    float t = threshold.hotThrottlingThresholds[severity];
+                    if (Float.isNaN(t)) {
+                        continue;
                     }
-                    float headroom = normalizeTemperature(threshold, severeThreshold);
-                    if (Float.isNaN(mHeadroomThresholds[severity])) {
-                        mHeadroomThresholds[severity] = headroom;
-                    } else {
-                        float lastHeadroom = mHeadroomThresholds[severity];
-                        mHeadroomThresholds[severity] = Math.min(lastHeadroom, headroom);
+                    synchronized (mSamples) {
+                        if (severity == ThrottlingSeverity.SEVERE) {
+                            mHeadroomThresholds[severity] = 1.0f;
+                            continue;
+                        }
+                        float headroom = normalizeTemperature(t, severeThreshold);
+                        if (Float.isNaN(mHeadroomThresholds[severity])) {
+                            mHeadroomThresholds[severity] = headroom;
+                        } else {
+                            float lastHeadroom = mHeadroomThresholds[severity];
+                            mHeadroomThresholds[severity] = Math.min(lastHeadroom, headroom);
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/power/WakefulnessSessionObserver.java b/services/core/java/com/android/server/power/WakefulnessSessionObserver.java
index c6b2602..64f0693 100644
--- a/services/core/java/com/android/server/power/WakefulnessSessionObserver.java
+++ b/services/core/java/com/android/server/power/WakefulnessSessionObserver.java
@@ -49,6 +49,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.IndentingPrintWriter;
+import android.util.Slog;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.DisplayAddress;
@@ -70,12 +71,11 @@
 public class WakefulnessSessionObserver {
     private static final String TAG = "WakefulnessSessionObserver";
 
-    private static final int OFF_REASON_UNKNOWN = FrameworkStatsLog
+    static final int OFF_REASON_UNKNOWN = FrameworkStatsLog
             .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__UNKNOWN;
-    private static final int OFF_REASON_TIMEOUT = FrameworkStatsLog
+    static final int OFF_REASON_TIMEOUT = FrameworkStatsLog
             .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__TIMEOUT;
-    @VisibleForTesting
-    protected static final int OFF_REASON_POWER_BUTTON = FrameworkStatsLog
+    static final int OFF_REASON_POWER_BUTTON = FrameworkStatsLog
             .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__POWER_BUTTON;
 
     /**
@@ -90,25 +90,21 @@
     @Retention(RetentionPolicy.SOURCE)
     private @interface OffReason {}
 
-    private static final int OVERRIDE_OUTCOME_UNKNOWN = FrameworkStatsLog
+    static final int OVERRIDE_OUTCOME_UNKNOWN = FrameworkStatsLog
             .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__UNKNOWN;
-    @VisibleForTesting
-    protected static final int OVERRIDE_OUTCOME_TIMEOUT_SUCCESS = FrameworkStatsLog
+    static final int OVERRIDE_OUTCOME_TIMEOUT_SUCCESS = FrameworkStatsLog
             .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__TIMEOUT_SUCCESS;
-    @VisibleForTesting
-    protected static final int OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT = FrameworkStatsLog
+    static final int OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT = FrameworkStatsLog
             .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__TIMEOUT_USER_INITIATED_REVERT;
-    private static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_API_CALL = FrameworkStatsLog
+    static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_API_CALL = FrameworkStatsLog
             .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_CLIENT_API_CALL;
-    @VisibleForTesting
-    protected static final int OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION = FrameworkStatsLog
+    static final int OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION = FrameworkStatsLog
             .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_USER_INTERACTION;
-    @VisibleForTesting
-    protected static final int OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON = FrameworkStatsLog
+    static final int OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON = FrameworkStatsLog
             .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_POWER_BUTTON;
-    private static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_DISCONNECT = FrameworkStatsLog
+    static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_DISCONNECT = FrameworkStatsLog
             .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_CLIENT_DISCONNECTED;
-    private static final int OVERRIDE_OUTCOME_CANCEL_OTHER = FrameworkStatsLog
+    static final int OVERRIDE_OUTCOME_CANCEL_OTHER = FrameworkStatsLog
             .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_OTHER;
 
     /**
@@ -128,19 +124,15 @@
     @Retention(RetentionPolicy.SOURCE)
     private @interface OverrideOutcome {}
 
-    private static final int POLICY_REASON_UNKNOWN = FrameworkStatsLog
+    static final int POLICY_REASON_UNKNOWN = FrameworkStatsLog
             .SCREEN_DIM_REPORTED__POLICY_REASON__UNKNOWN;
-    @VisibleForTesting
-    protected static final int POLICY_REASON_OFF_TIMEOUT = FrameworkStatsLog
+    static final int POLICY_REASON_OFF_TIMEOUT = FrameworkStatsLog
             .SCREEN_DIM_REPORTED__POLICY_REASON__OFF_TIMEOUT;
-    @VisibleForTesting
-    protected static final int POLICY_REASON_OFF_POWER_BUTTON = FrameworkStatsLog
+    static final int POLICY_REASON_OFF_POWER_BUTTON = FrameworkStatsLog
             .SCREEN_DIM_REPORTED__POLICY_REASON__OFF_POWER_BUTTON;
-    @VisibleForTesting
-    protected static final int POLICY_REASON_BRIGHT_UNDIM = FrameworkStatsLog
+    static final int POLICY_REASON_BRIGHT_UNDIM = FrameworkStatsLog
             .SCREEN_DIM_REPORTED__POLICY_REASON__BRIGHT_UNDIM;
-    @VisibleForTesting
-    protected static final int POLICY_REASON_BRIGHT_INITIATED_REVERT = FrameworkStatsLog
+    static final int POLICY_REASON_BRIGHT_INITIATED_REVERT = FrameworkStatsLog
             .SCREEN_DIM_REPORTED__POLICY_REASON__BRIGHT_INITIATED_REVERT;
 
     /**
@@ -157,21 +149,18 @@
     @Retention(RetentionPolicy.SOURCE)
     private @interface PolicyReason {}
 
-    @VisibleForTesting protected static final int DEFAULT_USER_ACTIVITY = USER_ACTIVITY_EVENT_OTHER;
-    private static final long USER_INITIATED_REVERT_THRESHOLD_MILLIS = 5000L;
-    private static final long SEND_OVERRIDE_TIMEOUT_LOG_THRESHOLD_MILLIS = 1000L;
-    @VisibleForTesting
-    protected static final long SCREEN_POLICY_DIM_POWER_OFF_BRIGHT_THRESHOLD_MILLIS = 500L;
+    static final int DEFAULT_USER_ACTIVITY = USER_ACTIVITY_EVENT_OTHER;
+    static final long USER_INITIATED_REVERT_THRESHOLD_MILLIS = 5000L;
+    static final long SEND_OVERRIDE_TIMEOUT_LOG_THRESHOLD_MILLIS = 1000L;
+    static final long SCREEN_POLICY_DIM_POWER_OFF_BRIGHT_THRESHOLD_MILLIS = 500L;
 
-    @VisibleForTesting protected static final Object HANDLER_TOKEN = new Object();
+    static final Object HANDLER_TOKEN = new Object();
 
     private Context mContext;
     private int mScreenOffTimeoutMs;
     private int mOverrideTimeoutMs = 0;
-    @VisibleForTesting
-    protected final SparseArray<WakefulnessSessionPowerGroup> mPowerGroups = new SparseArray<>();
-    @VisibleForTesting
-    protected WakefulnessSessionFrameworkStatsLogger mWakefulnessSessionFrameworkStatsLogger;
+    final SparseArray<WakefulnessSessionPowerGroup> mPowerGroups = new SparseArray<>();
+    WakefulnessSessionFrameworkStatsLogger mWakefulnessSessionFrameworkStatsLogger;
     private final Clock mClock;
     private final Object mLock = new Object();
     private final Handler mHandler;
@@ -347,7 +336,8 @@
         writer.println();
     }
 
-    private void updateSettingScreenOffTimeout(Context context) {
+    @VisibleForTesting
+    void updateSettingScreenOffTimeout(Context context) {
         synchronized (mLock) {
             mScreenOffTimeoutMs = Settings.System.getIntForUser(
                     context.getContentResolver(),
@@ -453,6 +443,7 @@
                 return;
             }
 
+            final int screenOffTimeoutMs = getScreenOffTimeout();
             mIsInteractive = isInteractive(wakefulness);
             if (mIsInteractive) {
                 mInteractiveStateOnStartTimestamp = eventTime;
@@ -466,7 +457,7 @@
                                 mPowerGroupId,
                                 OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT,
                                 mOverrideTimeoutMs,
-                                getScreenOffTimeout());
+                                screenOffTimeoutMs);
                         mSendOverrideTimeoutLogTimestamp = eventTime;
                     }
                     mTimeoutOffTimestamp = TIMEOUT_OFF_RESET_TIMESTAMP;
@@ -496,7 +487,7 @@
                                 mPowerGroupId,
                                 OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON,
                                 mOverrideTimeoutMs,
-                                getScreenOffTimeout());
+                                screenOffTimeoutMs);
                         mSendOverrideTimeoutLogTimestamp = eventTime;
                         mTimeoutOverrideReleaseReason = RELEASE_REASON_UNKNOWN; // reset the reason
                     }
@@ -514,13 +505,12 @@
                     // timeout has been done successfully.
                     if (isInOverrideTimeout()) {
                         reducedInteractiveStateOnDurationMs =
-                                getScreenOffTimeout() - mOverrideTimeoutMs;
-
+                                screenOffTimeoutMs - mOverrideTimeoutMs;
                         mWakefulnessSessionFrameworkStatsLogger.logTimeoutOverrideEvent(
                                 mPowerGroupId,
                                 OVERRIDE_OUTCOME_TIMEOUT_SUCCESS,
                                 mOverrideTimeoutMs,
-                                getScreenOffTimeout());
+                                screenOffTimeoutMs);
                         mSendOverrideTimeoutLogTimestamp = eventTime;
 
                         // Record a timestamp to track if the user initiates to revert from off
@@ -533,13 +523,21 @@
 
                 long interactiveStateOnDurationMs =
                         eventTime - mInteractiveStateOnStartTimestamp;
-                mWakefulnessSessionFrameworkStatsLogger.logSessionEvent(
-                        mPowerGroupId,
-                        interactiveStateOffReason,
-                        interactiveStateOnDurationMs,
-                        lastUserActivity,
-                        lastUserActivityDurationMs,
-                        reducedInteractiveStateOnDurationMs);
+
+                if (reducedInteractiveStateOnDurationMs < screenOffTimeoutMs
+                        && reducedInteractiveStateOnDurationMs >= 0) {
+                    mWakefulnessSessionFrameworkStatsLogger.logSessionEvent(
+                            mPowerGroupId,
+                            interactiveStateOffReason,
+                            interactiveStateOnDurationMs,
+                            lastUserActivity,
+                            lastUserActivityDurationMs,
+                            reducedInteractiveStateOnDurationMs);
+                } else {
+                    Slog.w(TAG, "invalid reducedInteractiveStateOnDurationMs: "
+                            + reducedInteractiveStateOnDurationMs);
+                }
+
             }
         }
 
@@ -608,6 +606,7 @@
                 return;
             }
 
+            final int screenOffTimeoutMs = getScreenOffTimeout();
             int dimDurationMs = 0;
             int lastUserActivity = mCurrentUserActivityEvent;
             int lastUserActivityDurationMs = (int) (eventTime - mCurrentUserActivityTimestamp);
@@ -625,7 +624,7 @@
                             lastUserActivity,
                             lastUserActivityDurationMs,
                             dimDurationMs,
-                            mScreenOffTimeoutMs);
+                            screenOffTimeoutMs);
                     mPastDimDurationMs = dimDurationMs;
                     return;
                 }
@@ -645,7 +644,7 @@
                                 lastUserActivity,
                                 lastUserActivityDurationMs,
                                 dimDurationMs,
-                                mScreenOffTimeoutMs);
+                                screenOffTimeoutMs);
                         mHandler.removeCallbacksAndMessages(HANDLER_TOKEN);
                     }
 
@@ -674,7 +673,7 @@
                                     savedLastUserActivity,
                                     savedLastUserActivityDurationMs,
                                     savedDimDurationMs,
-                                    mScreenOffTimeoutMs);
+                                    screenOffTimeoutMs);
                             mPastDimDurationMs = savedDimDurationMs;
                         }, HANDLER_TOKEN, SCREEN_POLICY_DIM_POWER_OFF_BRIGHT_THRESHOLD_MILLIS);
                     }
@@ -692,7 +691,7 @@
                                 lastUserActivity,
                                 lastUserActivityDurationMs,
                                 mPastDimDurationMs,
-                                mScreenOffTimeoutMs);
+                                screenOffTimeoutMs);
                     }
                     return;
                 }
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
index 68760aa..4d63fdf 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
@@ -959,9 +959,10 @@
                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
                 .putExtra(EXTRA_SHOW_FRAGMENT_TITLE, highlightBundle);
 
-        PendingIntent batterySaverIntent = PendingIntent.getActivity(
+        PendingIntent batterySaverIntent = PendingIntent.getActivityAsUser(
                 mContext, 0 /* requestCode */, intent,
-                PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
+                PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT,
+                null /* options */, UserHandle.CURRENT);
         final String title = res.getString(titleId);
         final String summary = res.getString(summaryId);
 
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 2c4179f..0d98707 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1757,6 +1757,13 @@
             startedActivityRootTask.setAlwaysOnTop(true);
         }
 
+        if (isIndependentLaunch && !mDoResume && avoidMoveToFront() && !mTransientLaunch
+                && !started.shouldBeVisible(true /* ignoringKeyguard */)) {
+            Slog.i(TAG, "Abort " + transition + " of invisible launch " + started);
+            transition.abort();
+            return startedActivityRootTask;
+        }
+
         // If there is no state change (e.g. a resumed activity is reparented to top of
         // another display) to trigger a visibility/configuration checking, we have to
         // update the configuration for changing to different display.
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 04a625b..5b2fecd 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -65,10 +65,6 @@
 import static android.view.WindowManagerGlobal.ADD_OKAY;
 import static android.view.WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED;
 import static android.view.WindowManagerPolicyConstants.EXTRA_HDMI_PLUGGED_STATE;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
 import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
 
 import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_ANIM;
@@ -109,7 +105,6 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.DisplayInfo;
-import android.view.Gravity;
 import android.view.InsetsFlags;
 import android.view.InsetsFrameProvider;
 import android.view.InsetsSource;
@@ -142,7 +137,6 @@
 import com.android.internal.widget.PointerLocationView;
 import com.android.server.LocalServices;
 import com.android.server.UiThread;
-import com.android.server.policy.WindowManagerPolicy.NavigationBarPosition;
 import com.android.server.policy.WindowManagerPolicy.ScreenOnListener;
 import com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs;
 import com.android.server.statusbar.StatusBarManagerInternal;
@@ -263,8 +257,7 @@
     private WindowState mStatusBar = null;
     private volatile WindowState mNotificationShade;
     private WindowState mNavigationBar = null;
-    @NavigationBarPosition
-    private int mNavigationBarPosition = NAV_BAR_BOTTOM;
+    private boolean mHasBottomNavigationBar = true;
 
     private final ArraySet<WindowState> mInsetsSourceWindowsExceptIme = new ArraySet<>();
 
@@ -1255,8 +1248,7 @@
                 throw new IllegalArgumentException("IME insets must be provided by a window.");
             }
 
-            if (!ENABLE_HIDE_IME_CAPTION_BAR && mNavigationBar != null
-                    && navigationBarPosition(displayFrames.mRotation) == NAV_BAR_BOTTOM) {
+            if (!ENABLE_HIDE_IME_CAPTION_BAR && mNavigationBar != null && mHasBottomNavigationBar) {
                 // In gesture navigation, nav bar frame is larger than frame to calculate insets.
                 // IME should not provide frame which is smaller than the nav bar frame. Otherwise,
                 // nav bar might be overlapped with the content of the client when IME is shown.
@@ -1469,10 +1461,9 @@
     public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs,
             WindowState attached, WindowState imeTarget) {
         if (attrs.type == TYPE_NAVIGATION_BAR) {
-            // Keep mNavigationBarPosition updated to make sure the transient detection and bar
-            // color control is working correctly.
-            final DisplayFrames displayFrames = mDisplayContent.mDisplayFrames;
-            mNavigationBarPosition = navigationBarPosition(displayFrames.mRotation);
+            // Keep mHasBottomNavigationBar updated to make sure the bar color control is working
+            // correctly.
+            mHasBottomNavigationBar = hasBottomNavigationBar();
         }
         final boolean affectsSystemUi = win.canAffectSystemUiFlags();
         if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": affectsSystemUi=" + affectsSystemUi);
@@ -2230,20 +2221,11 @@
         mDisplayContent.mDisplayUpdater.onDisplaySwitching(true);
     }
 
-    @NavigationBarPosition
-    int navigationBarPosition(int displayRotation) {
-        if (mNavigationBar != null) {
-            final int gravity = mNavigationBar.mAttrs.forRotation(displayRotation).gravity;
-            switch (gravity) {
-                case Gravity.LEFT:
-                    return NAV_BAR_LEFT;
-                case Gravity.RIGHT:
-                    return NAV_BAR_RIGHT;
-                default:
-                    return NAV_BAR_BOTTOM;
-            }
-        }
-        return NAV_BAR_INVALID;
+    boolean hasBottomNavigationBar() {
+        Insets navBarInsets = mDisplayContent.getInsetsStateController().getRawInsetsState()
+                .calculateInsets(mDisplayContent.mDisplayFrames.mUnrestricted,
+                        Type.navigationBars(), true /* ignoreVisibilities */);
+        return navBarInsets.bottom > 0;
     }
 
     /**
@@ -2405,7 +2387,7 @@
             return;
         }
         final WindowState navColorWin = chooseNavigationColorWindowLw(mNavBarColorWindowCandidate,
-                mDisplayContent.mInputMethodWindow, mNavigationBarPosition);
+                mDisplayContent.mInputMethodWindow, mHasBottomNavigationBar);
         final boolean isNavbarColorManagedByIme =
                 navColorWin != null && navColorWin == mDisplayContent.mInputMethodWindow;
         final int appearance = updateLightNavigationBarLw(win.mAttrs.insetsFlags.appearance,
@@ -2467,12 +2449,12 @@
     @VisibleForTesting
     @Nullable
     static WindowState chooseNavigationColorWindowLw(WindowState candidate, WindowState imeWindow,
-            @NavigationBarPosition int navBarPosition) {
+            boolean hasBottomNavigationBar) {
         // If the IME window is visible and FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS is set, then IME
         // window can be navigation color window.
         final boolean imeWindowCanNavColorWindow = imeWindow != null
                 && imeWindow.isVisible()
-                && navBarPosition == NAV_BAR_BOTTOM
+                && hasBottomNavigationBar
                 && (imeWindow.mAttrs.flags
                         & WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
         if (!imeWindowCanNavColorWindow) {
@@ -2689,7 +2671,7 @@
         final WindowState navBackgroundWin = chooseNavigationBackgroundWindow(
                 mNavBarBackgroundWindowCandidate,
                 mDisplayContent.mInputMethodWindow,
-                mNavigationBarPosition);
+                mHasBottomNavigationBar);
         final boolean drawBackground = navBackgroundWin != null
                 // There is no app window showing underneath nav bar. (e.g., The screen is locked.)
                 // Let system windows (ex: notification shade) draw nav bar background.
@@ -2727,8 +2709,8 @@
     @VisibleForTesting
     @Nullable
     static WindowState chooseNavigationBackgroundWindow(WindowState candidate,
-            WindowState imeWindow, @NavigationBarPosition int navBarPosition) {
-        if (imeWindow != null && imeWindow.isVisible() && navBarPosition == NAV_BAR_BOTTOM
+            WindowState imeWindow, boolean hasBottomNavigationBar) {
+        if (imeWindow != null && imeWindow.isVisible() && hasBottomNavigationBar
                 && drawsBarBackground(imeWindow)) {
             return imeWindow;
         }
@@ -2906,8 +2888,8 @@
             pw.print(prefix); pw.print("mNavigationBar="); pw.println(mNavigationBar);
             pw.print(prefix); pw.print("mNavBarOpacityMode="); pw.println(mNavBarOpacityMode);
             pw.print(prefix); pw.print("mNavigationBarCanMove="); pw.println(mNavigationBarCanMove);
-            pw.print(prefix); pw.print("mNavigationBarPosition=");
-            pw.println(mNavigationBarPosition);
+            pw.print(prefix); pw.print("mHasBottomNavigationBar=");
+            pw.println(mHasBottomNavigationBar);
         }
         if (mLeftGestureHost != null) {
             pw.print(prefix); pw.print("mLeftGestureHost="); pw.println(mLeftGestureHost);
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index a5085fc..ea0b02c 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -191,7 +191,7 @@
         "android.hardware.power.stats@1.0",
         "android.hardware.power.stats-V1-ndk",
         "android.hardware.thermal@1.0",
-        "android.hardware.thermal-V2-ndk",
+        "android.hardware.thermal-V3-ndk",
         "android.hardware.tv.input@1.0",
         "android.hardware.tv.input-V2-ndk",
         "android.hardware.vibrator-V3-ndk",
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 248ed1a..416e60f 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -3056,6 +3056,12 @@
     im->setMouseSwapPrimaryButtonEnabled(enabled);
 }
 
+static jboolean nativeSetKernelWakeEnabled(JNIEnv* env, jobject nativeImplObj, jint deviceId,
+                                      jboolean enabled) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
+    return im->getInputManager()->getReader().setKernelWakeEnabled(deviceId, enabled);
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gInputManagerMethods[] = {
@@ -3172,6 +3178,7 @@
          (void*)nativeSetAccessibilityStickyKeysEnabled},
         {"setInputMethodConnectionIsActive", "(Z)V", (void*)nativeSetInputMethodConnectionIsActive},
         {"getLastUsedInputDeviceId", "()I", (void*)nativeGetLastUsedInputDeviceId},
+        {"setKernelWakeEnabled", "(IZ)Z", (void*)nativeSetKernelWakeEnabled},
 };
 
 #define FIND_CLASS(var, className) \
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 20c69ac..6eac826 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -955,6 +955,7 @@
             <xs:enumeration value="default"/>
             <xs:enumeration value="idle"/>
             <xs:enumeration value="doze"/>
+            <xs:enumeration value="bedtime_wear"/>
         </xs:restriction>
     </xs:simpleType>
 
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index a8f18b3..a29e42c 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -21,6 +21,7 @@
   public enum AutoBrightnessModeName {
     method public String getRawName();
     enum_constant public static final com.android.server.display.config.AutoBrightnessModeName _default;
+    enum_constant public static final com.android.server.display.config.AutoBrightnessModeName bedtime_wear;
     enum_constant public static final com.android.server.display.config.AutoBrightnessModeName doze;
     enum_constant public static final com.android.server.display.config.AutoBrightnessModeName idle;
   }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2461c1c..b87867a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1399,6 +1399,10 @@
         mSystemServiceManager.startService(BatteryService.class);
         t.traceEnd();
 
+        t.traceBegin("StartTradeInModeService");
+        mSystemServiceManager.startService(TradeInModeService.class);
+        t.traceEnd();
+
         // Tracks application usage stats.
         t.traceBegin("StartUsageService");
         mSystemServiceManager.startService(UsageStatsService.class);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
index 2c78504..2bc8af1 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
@@ -159,15 +159,16 @@
 
         // Press home key to hide soft keyboard.
         Log.i(TAG, "Press home");
-        verifyInputViewStatus(
-                () -> assertThat(mUiDevice.pressHome()).isTrue(),
-                true /* expected */,
-                false /* inputViewStarted */);
         if (Flags.refactorInsetsController()) {
+            assertThat(mUiDevice.pressHome()).isTrue();
             // The IME visibility is only sent at the end of the animation. Therefore, we have to
             // wait until the visibility was sent to the server and the IME window hidden.
             eventually(() -> assertThat(mInputMethodService.isInputViewShown()).isFalse());
         } else {
+            verifyInputViewStatus(
+                    () -> assertThat(mUiDevice.pressHome()).isTrue(),
+                    true /* expected */,
+                    false /* inputViewStarted */);
             assertThat(mInputMethodService.isInputViewShown()).isFalse();
         }
     }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 2220f43..2fd135e 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -18,6 +18,7 @@
 
 
 import static com.android.internal.display.BrightnessSynchronizer.brightnessIntToFloat;
+import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE;
 import static com.android.server.display.config.SensorData.TEMPERATURE_TYPE_SKIN;
@@ -885,6 +886,34 @@
                 mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(
                         AUTO_BRIGHTNESS_MODE_DOZE,
                         Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_DIM), SMALL_DELTA);
+
+        // Wear Bedtime mode curve
+        assertArrayEquals(new float[]{0.0f, 10.0f},
+                mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(
+                        AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR,
+                        Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_DIM), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.20f, 0.30f},
+                mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(
+                        AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR,
+                        Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_DIM), SMALL_DELTA);
+
+        assertArrayEquals(new float[]{0.0f, 20.0f},
+                mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(
+                        AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR,
+                        Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_NORMAL), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.30f, 0.65f},
+                mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(
+                        AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR,
+                        Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_NORMAL), SMALL_DELTA);
+
+        assertArrayEquals(new float[]{0.0f, 30.0f},
+                mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(
+                        AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR,
+                        Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_BRIGHT), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.65f, 0.95f},
+                mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(
+                        AUTO_BRIGHTNESS_MODE_BEDTIME_WEAR,
+                        Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_BRIGHT), SMALL_DELTA);
     }
 
     @Test
@@ -1296,6 +1325,51 @@
                 +   "</screenBrightnessRampSlowIncreaseIdle>\n";
     }
 
+    private String getBedTimeModeWearCurveConfig() {
+        return  "<luxToBrightnessMapping>\n"
+                +           "<mode>bedtime_wear</mode>\n"
+                +           "<setting>dim</setting>\n"
+                +           "<map>\n"
+                +               "<point>\n"
+                +                   "<first>0</first>\n"
+                +                   "<second>0.2</second>\n"
+                +               "</point>\n"
+                +               "<point>\n"
+                +                   "<first>10</first>\n"
+                +                   "<second>0.3</second>\n"
+                +               "</point>\n"
+                +           "</map>\n"
+                +       "</luxToBrightnessMapping>\n"
+                +       "<luxToBrightnessMapping>\n"
+                +           "<mode>bedtime_wear</mode>\n"
+                +           "<setting>normal</setting>\n"
+                +           "<map>\n"
+                +               "<point>\n"
+                +                   "<first>0</first>\n"
+                +                   "<second>0.3</second>\n"
+                +               "</point>\n"
+                +               "<point>\n"
+                +                   "<first>20</first>\n"
+                +                   "<second>0.65</second>\n"
+                +               "</point>\n"
+                +           "</map>\n"
+                +       "</luxToBrightnessMapping>\n"
+                +       "<luxToBrightnessMapping>\n"
+                +           "<mode>bedtime_wear</mode>\n"
+                +           "<setting>bright</setting>\n"
+                +           "<map>\n"
+                +               "<point>\n"
+                +                   "<first>0</first>\n"
+                +                   "<second>0.65</second>\n"
+                +               "</point>\n"
+                +               "<point>\n"
+                +                   "<first>30</first>\n"
+                +                   "<second>0.95</second>\n"
+                +               "</point>\n"
+                +           "</map>\n"
+                +       "</luxToBrightnessMapping>\n";
+    }
+
     private String getPowerThrottlingConfig() {
         return  "<powerThrottlingConfig >\n"
                 +       "<brightnessLowestCapAllowed>0.1</brightnessLowestCapAllowed>\n"
@@ -1481,6 +1555,7 @@
                 +               "</point>\n"
                 +           "</map>\n"
                 +       "</luxToBrightnessMapping>\n"
+                +       getBedTimeModeWearCurveConfig()
                 +       "<idleStylusTimeoutMillis>1000</idleStylusTimeoutMillis>\n"
                 +   "</autoBrightness>\n"
                 +  getPowerThrottlingConfig()
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/ThermalManagerServiceMockingTest.java b/services/tests/mockingservicestests/src/com/android/server/power/ThermalManagerServiceMockingTest.java
index aa9d8c6..f1072da 100644
--- a/services/tests/mockingservicestests/src/com/android/server/power/ThermalManagerServiceMockingTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/power/ThermalManagerServiceMockingTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
@@ -29,10 +30,16 @@
 import android.hardware.thermal.ThrottlingSeverity;
 import android.os.Binder;
 import android.os.CoolingDevice;
+import android.os.Flags;
 import android.os.RemoteException;
 import android.os.Temperature;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 
 import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
@@ -40,16 +47,36 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
 
 public class ThermalManagerServiceMockingTest {
-    @Mock private IThermal mAidlHalMock;
+    @ClassRule
+    public static final SetFlagsRule.ClassRule mSetFlagsClassRule = new SetFlagsRule.ClassRule();
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = mSetFlagsClassRule.createSetFlagsRule();
+
+    @Mock
+    private IThermal mAidlHalMock;
     private Binder mAidlBinder = new Binder();
     private CompletableFuture<Temperature> mTemperatureFuture;
-    private ThermalManagerService.ThermalHalWrapper.TemperatureChangedCallback mTemperatureCallback;
+    private CompletableFuture<TemperatureThreshold> mThresholdFuture;
+    private ThermalManagerService.ThermalHalWrapper.WrapperThermalChangedCallback
+            mTemperatureCallback =
+            new ThermalManagerService.ThermalHalWrapper.WrapperThermalChangedCallback() {
+                @Override
+                public void onTemperatureChanged(Temperature temperature) {
+                    mTemperatureFuture.complete(temperature);
+                }
+
+                @Override
+                public void onThresholdChanged(TemperatureThreshold threshold) {
+                    mThresholdFuture.complete(threshold);
+                }
+            };
     private ThermalManagerService.ThermalHalAidlWrapper mAidlWrapper;
     @Captor
     ArgumentCaptor<IThermalChangedCallback> mAidlCallbackCaptor;
@@ -60,27 +87,63 @@
         Mockito.when(mAidlHalMock.asBinder()).thenReturn(mAidlBinder);
         mAidlBinder.attachInterface(mAidlHalMock, IThermal.class.getName());
         mTemperatureFuture = new CompletableFuture<>();
-        mTemperatureCallback = temperature -> mTemperatureFuture.complete(temperature);
+        mThresholdFuture = new CompletableFuture<>();
         mAidlWrapper = new ThermalManagerService.ThermalHalAidlWrapper(mTemperatureCallback);
         mAidlWrapper.initProxyAndRegisterCallback(mAidlBinder);
     }
 
     @Test
+    @EnableFlags({Flags.FLAG_ALLOW_THERMAL_THRESHOLDS_CALLBACK})
     public void setCallback_aidl() throws Exception {
         Mockito.verify(mAidlHalMock, Mockito.times(1)).registerThermalChangedCallback(
                 mAidlCallbackCaptor.capture());
-        android.hardware.thermal.Temperature halT =
+        android.hardware.thermal.Temperature halTemperature =
                 new android.hardware.thermal.Temperature();
-        halT.type = TemperatureType.SOC;
-        halT.name = "test";
-        halT.throttlingStatus = ThrottlingSeverity.SHUTDOWN;
-        halT.value = 99.0f;
-        mAidlCallbackCaptor.getValue().notifyThrottling(halT);
+        halTemperature.type = TemperatureType.SOC;
+        halTemperature.name = "test";
+        halTemperature.throttlingStatus = ThrottlingSeverity.SHUTDOWN;
+        halTemperature.value = 99.0f;
+
+        android.hardware.thermal.TemperatureThreshold halThreshold =
+                new android.hardware.thermal.TemperatureThreshold();
+        halThreshold.type = TemperatureType.SKIN;
+        halThreshold.name = "test";
+        halThreshold.hotThrottlingThresholds = new float[ThrottlingSeverity.SHUTDOWN + 1];
+        Arrays.fill(halThreshold.hotThrottlingThresholds, Float.NaN);
+        halThreshold.hotThrottlingThresholds[ThrottlingSeverity.SEVERE] = 44.0f;
+
+        mAidlCallbackCaptor.getValue().notifyThrottling(halTemperature);
+        mAidlCallbackCaptor.getValue().notifyThresholdChanged(halThreshold);
+
         Temperature temperature = mTemperatureFuture.get(100, TimeUnit.MILLISECONDS);
-        assertEquals(halT.name, temperature.getName());
-        assertEquals(halT.type, temperature.getType());
-        assertEquals(halT.value, temperature.getValue(), 0.1f);
-        assertEquals(halT.throttlingStatus, temperature.getStatus());
+        assertEquals(halTemperature.name, temperature.getName());
+        assertEquals(halTemperature.type, temperature.getType());
+        assertEquals(halTemperature.value, temperature.getValue(), 0.1f);
+        assertEquals(halTemperature.throttlingStatus, temperature.getStatus());
+
+        TemperatureThreshold threshold = mThresholdFuture.get(100, TimeUnit.MILLISECONDS);
+        assertEquals(halThreshold.name, threshold.name);
+        assertEquals(halThreshold.type, threshold.type);
+        assertArrayEquals(halThreshold.hotThrottlingThresholds, threshold.hotThrottlingThresholds,
+                0.01f);
+    }
+
+    @Test
+    @DisableFlags({Flags.FLAG_ALLOW_THERMAL_THRESHOLDS_CALLBACK})
+    public void setCallback_aidl_allow_thermal_thresholds_callback_false() throws Exception {
+        Mockito.verify(mAidlHalMock, Mockito.times(1)).registerThermalChangedCallback(
+                mAidlCallbackCaptor.capture());
+        android.hardware.thermal.TemperatureThreshold halThreshold =
+                new android.hardware.thermal.TemperatureThreshold();
+        halThreshold.type = TemperatureType.SOC;
+        halThreshold.name = "test";
+        halThreshold.hotThrottlingThresholds = new float[ThrottlingSeverity.SHUTDOWN + 1];
+        Arrays.fill(halThreshold.hotThrottlingThresholds, Float.NaN);
+        halThreshold.hotThrottlingThresholds[ThrottlingSeverity.SEVERE] = 44.0f;
+
+        mAidlCallbackCaptor.getValue().notifyThresholdChanged(halThreshold);
+        Thread.sleep(1000);
+        assertFalse(mThresholdFuture.isDone());
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
index b7100ea..c9e9f00 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.audio;
 
+import static android.media.AudioDeviceInfo.TYPE_BUILTIN_MIC;
+
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -27,16 +29,20 @@
 
 import android.app.AppOpsManager;
 import android.content.Context;
+import android.media.AudioDeviceAttributes;
 import android.media.AudioSystem;
 import android.os.Looper;
 import android.os.PermissionEnforcer;
 import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
 import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.MediumTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.media.flags.Flags;
+
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
@@ -53,6 +59,7 @@
     private static final String TAG = "AudioServiceTest";
 
     private static final int MAX_MESSAGE_HANDLING_DELAY_MS = 100;
+    private static final int DEFAULT_INPUT_GAIN_INDEX = 50;
 
     @Rule
     public final MockitoRule mockito = MockitoJUnit.rule();
@@ -202,4 +209,29 @@
             reset(mSpySystemServer);
         }
     }
+
+    /** Test input gain index setter and getter */
+    @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+    @Test
+    public void testInputGainIndex() throws Exception {
+        Log.i(TAG, "running testInputGainIndex");
+        Assert.assertNotNull(mAudioService);
+        Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS); // wait for full AudioService initialization
+
+        AudioDeviceAttributes ada =
+                new AudioDeviceAttributes(
+                        AudioDeviceAttributes.ROLE_INPUT, TYPE_BUILTIN_MIC, /* address= */ "");
+
+        Assert.assertEquals(
+                "default input gain index reporting wrong value",
+                DEFAULT_INPUT_GAIN_INDEX,
+                mAudioService.getInputGainIndex(ada));
+
+        int inputGainIndex = 20;
+        mAudioService.setInputGainIndex(ada, inputGainIndex);
+        Assert.assertEquals(
+                "input gain index reporting wrong value",
+                inputGainIndex,
+                mAudioService.getInputGainIndex(ada));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
index a2e6d4c..93aa10b 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
@@ -135,7 +135,6 @@
     @Mock PlatformCompat mPlatformCompat;
     @Mock Context mMockContext;
     @Mock Resources mMockResources;
-    @Mock IntegrityFileManager mIntegrityFileManager;
     @Mock Handler mHandler;
 
     private final Context mRealContext = InstrumentationRegistry.getTargetContext();
@@ -169,7 +168,6 @@
                 new AppIntegrityManagerServiceImpl(
                         mMockContext,
                         mPackageManagerInternal,
-                        mIntegrityFileManager,
                         mHandler);
 
         mSpyPackageManager = spy(mRealContext.getPackageManager());
@@ -177,7 +175,6 @@
         when(mMockContext.getPackageManager()).thenReturn(mSpyPackageManager);
         when(mMockContext.getResources()).thenReturn(mMockResources);
         when(mMockResources.getStringArray(anyInt())).thenReturn(new String[] {});
-        when(mIntegrityFileManager.initialized()).thenReturn(true);
         // These are needed to override the Settings.Global.get result.
         when(mMockContext.getContentResolver()).thenReturn(mRealContext.getContentResolver());
         setIntegrityCheckIncludesRuleProvider(true);
@@ -224,71 +221,6 @@
                         1, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
     }
 
-    @Test
-    public void handleBroadcast_notInitialized() throws Exception {
-        allowlistUsAsRuleProvider();
-        makeUsSystemApp();
-        when(mIntegrityFileManager.initialized()).thenReturn(false);
-        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mMockContext)
-                .registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
-        Intent intent = makeVerificationIntent();
-
-        broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent);
-        runJobInHandler();
-
-        // The evaluation will still run since we still evaluate manifest based rules.
-        verify(mPackageManagerInternal)
-                .setIntegrityVerificationResult(
-                        1, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
-    }
-
-    @Test
-    public void verifierAsInstaller_skipIntegrityVerification() throws Exception {
-        allowlistUsAsRuleProvider();
-        makeUsSystemApp();
-        setIntegrityCheckIncludesRuleProvider(false);
-        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mMockContext, atLeastOnce())
-                .registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
-        Intent intent = makeVerificationIntent(TEST_FRAMEWORK_PACKAGE);
-
-        broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent);
-        runJobInHandler();
-
-        verify(mPackageManagerInternal)
-                .setIntegrityVerificationResult(
-                        1, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
-    }
-
-    @Test
-    public void getCurrentRules() throws Exception {
-        allowlistUsAsRuleProvider();
-        makeUsSystemApp();
-        Rule rule = new Rule(IntegrityFormula.Application.packageNameEquals("package"), Rule.DENY);
-        when(mIntegrityFileManager.readRules(any())).thenReturn(Arrays.asList(rule));
-
-        assertThat(mService.getCurrentRules().getList()).containsExactly(rule);
-    }
-
-    @Test
-    public void getWhitelistedRuleProviders_returnsEmptyForNonSystemApps() throws Exception {
-        allowlistUsAsRuleProvider();
-        makeUsSystemApp(false);
-
-        assertThat(mService.getWhitelistedRuleProviders()).isEmpty();
-    }
-
-    @Test
-    public void getWhitelistedRuleProviders() throws Exception {
-        allowlistUsAsRuleProvider();
-        makeUsSystemApp();
-
-        assertThat(mService.getWhitelistedRuleProviders()).containsExactly(TEST_FRAMEWORK_PACKAGE);
-    }
-
     private void allowlistUsAsRuleProvider() {
         Resources mockResources = mock(Resources.class);
         when(mockResources.getStringArray(R.array.config_integrityRuleProviderPackages))
diff --git a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
index 6d79ae4..cfe3d84 100644
--- a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
@@ -296,11 +296,11 @@
     }
 
     @Test
-    public void testNotify() throws RemoteException {
+    public void testNotifyThrottling() throws RemoteException {
         int status = Temperature.THROTTLING_SEVERE;
         // Should only notify event not status
         Temperature newBattery = new Temperature(50, Temperature.TYPE_BATTERY, "batt", status);
-        mFakeHal.mCallback.onValues(newBattery);
+        mFakeHal.mCallback.onTemperatureChanged(newBattery);
         verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(1)).notifyThrottling(newBattery);
         verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
@@ -312,7 +312,7 @@
         resetListenerMock();
         // Notify both event and status
         Temperature newSkin = new Temperature(50, Temperature.TYPE_SKIN, "skin1", status);
-        mFakeHal.mCallback.onValues(newSkin);
+        mFakeHal.mCallback.onTemperatureChanged(newSkin);
         verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(1)).notifyThrottling(newSkin);
         verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
@@ -325,7 +325,7 @@
         // Back to None, should only notify event not status
         status = Temperature.THROTTLING_NONE;
         newBattery = new Temperature(50, Temperature.TYPE_BATTERY, "batt", status);
-        mFakeHal.mCallback.onValues(newBattery);
+        mFakeHal.mCallback.onTemperatureChanged(newBattery);
         verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(1)).notifyThrottling(newBattery);
         verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
@@ -337,7 +337,7 @@
         resetListenerMock();
         // Should also notify status
         newSkin = new Temperature(50, Temperature.TYPE_SKIN, "skin1", status);
-        mFakeHal.mCallback.onValues(newSkin);
+        mFakeHal.mCallback.onTemperatureChanged(newSkin);
         verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(1)).notifyThrottling(newSkin);
         verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
@@ -362,7 +362,7 @@
     public void testGetCurrentStatus() throws RemoteException {
         int status = Temperature.THROTTLING_SEVERE;
         Temperature newSkin = new Temperature(100, Temperature.TYPE_SKIN, "skin1", status);
-        mFakeHal.mCallback.onValues(newSkin);
+        mFakeHal.mCallback.onTemperatureChanged(newSkin);
         assertEquals(status, mService.mService.getCurrentThermalStatus());
         int battStatus = Temperature.THROTTLING_EMERGENCY;
         Temperature newBattery = new Temperature(60, Temperature.TYPE_BATTERY, "batt", battStatus);
@@ -373,11 +373,11 @@
     public void testThermalShutdown() throws RemoteException {
         int status = Temperature.THROTTLING_SHUTDOWN;
         Temperature newSkin = new Temperature(100, Temperature.TYPE_SKIN, "skin1", status);
-        mFakeHal.mCallback.onValues(newSkin);
+        mFakeHal.mCallback.onTemperatureChanged(newSkin);
         verify(mIPowerManagerMock, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(1)).shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
         Temperature newBattery = new Temperature(60, Temperature.TYPE_BATTERY, "batt", status);
-        mFakeHal.mCallback.onValues(newBattery);
+        mFakeHal.mCallback.onTemperatureChanged(newBattery);
         verify(mIPowerManagerMock, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(1)).shutdown(false, PowerManager.SHUTDOWN_BATTERY_THERMAL_STATE, false);
     }
@@ -419,15 +419,35 @@
     }
 
     @Test
-    public void testTemperatureWatcherUpdateSevereThresholds() throws RemoteException {
+    public void testTemperatureWatcherUpdateSevereThresholds() {
         TemperatureWatcher watcher = mService.mTemperatureWatcher;
-        watcher.mSevereThresholds.erase();
-        watcher.updateThresholds();
-        assertEquals(1, watcher.mSevereThresholds.size());
-        assertEquals("skin1", watcher.mSevereThresholds.keyAt(0));
-        Float threshold = watcher.mSevereThresholds.get("skin1");
-        assertNotNull(threshold);
-        assertEquals(40.0f, threshold, 0.0f);
+        synchronized (watcher.mSamples) {
+            watcher.mSevereThresholds.erase();
+            watcher.getAndUpdateThresholds();
+            assertEquals(1, watcher.mSevereThresholds.size());
+            assertEquals("skin1", watcher.mSevereThresholds.keyAt(0));
+            Float threshold = watcher.mSevereThresholds.get("skin1");
+            assertNotNull(threshold);
+            assertEquals(40.0f, threshold, 0.0f);
+            assertArrayEquals("Got" + Arrays.toString(watcher.mHeadroomThresholds),
+                    new float[]{Float.NaN, 0.6667f, 0.8333f, 1.0f, 1.166f, 1.3333f,
+                            1.5f},
+                    watcher.mHeadroomThresholds, 0.01f);
+
+            TemperatureThreshold newThreshold = new TemperatureThreshold();
+            newThreshold.name = "skin1";
+            newThreshold.hotThrottlingThresholds = new float[] {
+                    Float.NaN, 44.0f, 47.0f, 50.0f, Float.NaN, Float.NaN, Float.NaN
+            };
+            mFakeHal.mCallback.onThresholdChanged(newThreshold);
+            threshold = watcher.mSevereThresholds.get("skin1");
+            assertNotNull(threshold);
+            assertEquals(50.0f, threshold, 0.0f);
+            assertArrayEquals("Got" + Arrays.toString(watcher.mHeadroomThresholds),
+                    new float[]{Float.NaN, 0.8f, 0.9f, 1.0f, Float.NaN, Float.NaN,
+                            Float.NaN},
+                    watcher.mHeadroomThresholds, 0.01f);
+        }
     }
 
     @Test
@@ -436,25 +456,19 @@
         synchronized (watcher.mSamples) {
             Arrays.fill(watcher.mHeadroomThresholds, Float.NaN);
         }
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.LIGHT, 40, 49);
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.MODERATE, 46, 49);
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.SEVERE, 49, 49);
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.CRITICAL, 64, 49);
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.EMERGENCY, 70, 49);
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.SHUTDOWN, 79, 49);
+        TemperatureThreshold threshold = new TemperatureThreshold();
+        threshold.hotThrottlingThresholds = new float[]{Float.NaN, 40, 46, 49, 64, 70, 79};
         synchronized (watcher.mSamples) {
+            watcher.updateTemperatureThresholdLocked(threshold, false /*override*/);
             assertArrayEquals(new float[]{Float.NaN, 0.7f, 0.9f, 1.0f, 1.5f, 1.7f, 2.0f},
                     watcher.mHeadroomThresholds, 0.01f);
         }
 
         // when another sensor reports different threshold, we expect to see smaller one to be used
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.LIGHT, 37, 52);
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.MODERATE, 46, 52);
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.SEVERE, 52, 52);
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.CRITICAL, 64, 52);
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.EMERGENCY, 100, 52);
-        watcher.updateHeadroomThreshold(ThrottlingSeverity.SHUTDOWN, 200, 52);
+        threshold = new TemperatureThreshold();
+        threshold.hotThrottlingThresholds = new float[]{Float.NaN, 37, 46, 52, 64, 100, 200};
         synchronized (watcher.mSamples) {
+            watcher.updateTemperatureThresholdLocked(threshold, false /*override*/);
             assertArrayEquals(new float[]{Float.NaN, 0.5f, 0.8f, 1.0f, 1.4f, 1.7f, 2.0f},
                     watcher.mHeadroomThresholds, 0.01f);
         }
@@ -486,7 +500,7 @@
         TemperatureWatcher watcher = mService.mTemperatureWatcher;
         ArrayList<TemperatureThreshold> thresholds = new ArrayList<>();
         mFakeHal.mTemperatureThresholdList = thresholds;
-        watcher.updateThresholds();
+        watcher.getAndUpdateThresholds();
         synchronized (watcher.mSamples) {
             assertArrayEquals(
                     new float[]{Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN,
@@ -501,7 +515,7 @@
         Arrays.fill(nanThresholds.hotThrottlingThresholds, Float.NaN);
         Arrays.fill(nanThresholds.coldThrottlingThresholds, Float.NaN);
         thresholds.add(nanThresholds);
-        watcher.updateThresholds();
+        watcher.getAndUpdateThresholds();
         synchronized (watcher.mSamples) {
             assertArrayEquals(
                     new float[]{Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN,
diff --git a/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java b/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java
index 6b32be0..1af366b 100644
--- a/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java
@@ -28,6 +28,7 @@
 import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN;
 import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_TOUCH;
 import static com.android.server.power.WakefulnessSessionObserver.OFF_REASON_POWER_BUTTON;
+import static com.android.server.power.WakefulnessSessionObserver.OFF_REASON_TIMEOUT;
 import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON;
 import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION;
 import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_TIMEOUT_SUCCESS;
@@ -40,6 +41,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -90,6 +92,7 @@
             mWakefulnessSessionFrameworkStatsLogger;
     @Mock
     private DisplayManagerInternal mDisplayManagerInternal;
+    private MockContentResolver mContentResolver = new MockContentResolver();
 
     private TestHandler mHandler;
     @Before
@@ -106,10 +109,9 @@
                 R.integer.config_screenTimeoutOverride);
         when(mContext.getResources()).thenReturn(res);
         FakeSettingsProvider.clearSettingsProvider();
-        MockContentResolver mockContentResolver = new MockContentResolver();
-        mockContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
-        when(mContext.getContentResolver()).thenReturn(mockContentResolver);
-        Settings.System.putIntForUser(mockContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
+        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        when(mContext.getContentResolver()).thenReturn(mContentResolver);
+        Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
                 DEFAULT_SCREEN_OFF_TIMEOUT_MS, UserHandle.USER_CURRENT);
 
         final DisplayInfo info = new DisplayInfo();
@@ -511,6 +513,115 @@
                         DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default Timeout Ms
     }
 
+    @Test
+    public void testScreenOffTimeout_normal_logSessionEventTriggered() {
+        int powerGroupId = 1;
+        int userActivity = PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY;
+        triggerLogSessionEvent(powerGroupId, userActivity);
+        verify(mWakefulnessSessionFrameworkStatsLogger)
+                .logSessionEvent(
+                        powerGroupId, // powerGroupId
+                        OFF_REASON_TIMEOUT, // interactiveStateOffReason
+                        0, // interactiveStateOnDurationMs
+                        userActivity, // userActivity
+                        0,  // lastUserActivityEventDurationMs
+                        DEFAULT_SCREEN_OFF_TIMEOUT_MS - OVERRIDE_SCREEN_OFF_TIMEOUT_MS
+                ); // reducedInteractiveStateOnDurationMs;
+    }
+
+    @Test
+    public void testScreenOffTimeout_zero_noLogSessionEventTriggered() {
+        // simulate adding an invalid screen_off_timeout value
+        Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
+                0, // invalid timeout value
+                UserHandle.USER_CURRENT);
+        mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);
+
+        try {
+            triggerLogSessionEvent();
+            verify(mWakefulnessSessionFrameworkStatsLogger, never())
+                    .logSessionEvent(anyInt(), anyInt(), anyLong(), anyInt(), anyLong(), anyInt());
+        } finally {
+            // rollback the original data
+            Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
+                    DEFAULT_SCREEN_OFF_TIMEOUT_MS, UserHandle.USER_CURRENT);
+            mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);
+        }
+    }
+
+    @Test
+    public void testScreenOffTimeout_negative_noLogSessionEventTriggered() {
+        // simulate adding an invalid screen_off_timeout value
+        Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
+                -1, // invalid timeout value
+                UserHandle.USER_CURRENT);
+        mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);
+
+        try {
+            triggerLogSessionEvent();
+            verify(mWakefulnessSessionFrameworkStatsLogger, never())
+                    .logSessionEvent(anyInt(), anyInt(), anyLong(), anyInt(), anyLong(), anyInt());
+        } finally {
+            // rollback the original data
+            Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
+                    DEFAULT_SCREEN_OFF_TIMEOUT_MS, UserHandle.USER_CURRENT);
+            mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);
+        }
+    }
+
+    @Test
+    public void testScreenOffTimeout_max_logSessionEventTriggered() {
+        // simulate adding the max screen_off_timeout value
+        int defaultTimeoutMs = Integer.MAX_VALUE;
+        Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
+                defaultTimeoutMs,
+                UserHandle.USER_CURRENT);
+        mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);
+
+        try {
+            int powerGroupId = 1;
+            int userActivity = PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY;
+            triggerLogSessionEvent(powerGroupId, userActivity);
+            verify(mWakefulnessSessionFrameworkStatsLogger)
+                    .logSessionEvent(
+                            powerGroupId, // powerGroupId
+                            OFF_REASON_TIMEOUT, // interactiveStateOffReason
+                            0, // interactiveStateOnDurationMs
+                            userActivity, // userActivity
+                            0,  // lastUserActivityEventDurationMs
+                            defaultTimeoutMs - OVERRIDE_SCREEN_OFF_TIMEOUT_MS
+                    ); // reducedInteractiveStateOnDurationMs;
+        } finally {
+            // rollback the original data
+            Settings.System.putIntForUser(mContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
+                    DEFAULT_SCREEN_OFF_TIMEOUT_MS, UserHandle.USER_CURRENT);
+            mWakefulnessSessionObserver.updateSettingScreenOffTimeout(mContext);
+        }
+    }
+
+    private void triggerLogSessionEvent() {
+        triggerLogSessionEvent(1, PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY);
+    }
+
+    private void triggerLogSessionEvent(int powerGroupId, int userActivity) {
+        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+                powerGroupId,
+                PowerManagerInternal.WAKEFULNESS_AWAKE,
+                WAKE_REASON_POWER_BUTTON,
+                mTestClock.now());
+        mWakefulnessSessionObserver.onWakeLockAcquired(
+                PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK);
+
+        long userActivityTime = mTestClock.now();
+        mWakefulnessSessionObserver.notifyUserActivity(
+                userActivityTime, powerGroupId, userActivity);
+        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+                powerGroupId,
+                PowerManagerInternal.WAKEFULNESS_DOZING,
+                GO_TO_SLEEP_REASON_TIMEOUT,
+                mTestClock.now());
+    }
+
     private void advanceTime(long timeMs) {
         mTestClock.fastForward(timeMs);
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/EventConditionProviderTest.java b/services/tests/uiservicestests/src/com/android/server/notification/EventConditionProviderTest.java
index 05210ac..fa1372d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/EventConditionProviderTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/EventConditionProviderTest.java
@@ -124,9 +124,12 @@
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_MODES_HSUM)
-    public void onBootComplete_waitsForUserSwitched() {
+    public void onBootComplete_loadsTrackersForSystemUser() {
         mService.onBootComplete();
-        assertThat(mService.getTrackers().size()).isEqualTo(0);
+
+        assertThat(mService.getTrackers().size()).isEqualTo(1);
+        assertThat(mService.getTrackers().keyAt(0)).isEqualTo(UserHandle.USER_SYSTEM);
+        assertThat(mService.getTrackers().valueAt(0).getUserId()).isEqualTo(UserHandle.USER_SYSTEM);
     }
 
     @Test
@@ -158,4 +161,21 @@
         assertThat(mService.getTrackers().keyAt(1)).isEqualTo(43);
         assertThat(mService.getTrackers().valueAt(1).getUserId()).isEqualTo(43);
     }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_MODES_HSUM)
+    public void onUserSwitched_sameUser_doesNothing() {
+        UserHandle someUser = UserHandle.of(42);
+        when(mUserManager.getProfiles(eq(42))).thenReturn(List.of(new UserInfo(42, "user 42", 0)));
+
+        mService.onUserSwitched(someUser);
+        assertThat(mService.getTrackers().size()).isEqualTo(1);
+        assertThat(mService.getTrackers().keyAt(0)).isEqualTo(42);
+        CalendarTracker originalTracker = mService.getTrackers().valueAt(0);
+
+        mService.onUserSwitched(someUser);
+        assertThat(mService.getTrackers().size()).isEqualTo(1);
+        assertThat(mService.getTrackers().keyAt(0)).isEqualTo(42);
+        assertThat(mService.getTrackers().valueAt(0)).isSameInstanceAs(originalTracker);
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index b92bdb5..36fa1b8 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -6391,6 +6391,30 @@
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_CLASSIFICATION)
+    public void testNotificationBundles_off_deletesData() throws Exception {
+        String xml = "<ranking version=\"1\">\n"
+                + "<package name=\"" + PKG_P + "\" uid=\"" + UID_P + "\">\n"
+                + "<channel id=\"android.app.social\" name=\"Social\" importance=\"2\"/>\n"
+                + "<channel id=\"android.app.news\" name=\"News\" importance=\"2\"/>\n"
+                + "<channel id=\"android.app.recs\" name=\"Recs\" importance=\"2\"/>\n"
+                + "<channel id=\"android.app.promotions\" name=\"Promos\" importance=\"2\"/>\n"
+                + "<channel id=\"keep.me\" name=\"name\" importance=\"2\" "
+                + "show_badge=\"true\" />\n"
+                + "</package></ranking>\n";
+
+        loadByteArrayXml(xml.getBytes(), false, USER_SYSTEM);
+
+        // verify 4 reserved channels are created
+        assertThat(mXmlHelper.getNotificationChannel(PKG_P, UID_P, NEWS_ID, true)).isNull();
+        assertThat(mXmlHelper.getNotificationChannel(PKG_P, UID_P, PROMOTIONS_ID, true)).isNull();
+        assertThat(mXmlHelper.getNotificationChannel(PKG_P, UID_P, SOCIAL_MEDIA_ID, true)).isNull();
+        assertThat(mXmlHelper.getNotificationChannel(PKG_P, UID_P, RECS_ID, true)).isNull();
+        assertThat(mXmlHelper.getNotificationChannel(PKG_P, UID_P, "keep.me", false)
+                .getImportance()).isEqualTo(IMPORTANCE_LOW);
+    }
+
+    @Test
     @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION)
     public void testNotificationBundles_appsCannotUpdate() {
         // do something that triggers settings creation for an app
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
index fe4ce465e..52c3488 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
@@ -1,18 +1,38 @@
 package com.android.server.notification;
 
+import static android.app.AlarmManager.RTC_WAKEUP;
+
 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.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import static java.time.temporal.ChronoUnit.HOURS;
+import static java.time.temporal.ChronoUnit.MINUTES;
+
+import android.app.ActivityManager;
+import android.app.AlarmManager;
 import android.app.Application;
 import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.net.Uri;
+import android.os.Bundle;
+import android.os.SimpleClock;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.service.notification.Condition;
 import android.service.notification.ScheduleCalendar;
 import android.service.notification.ZenModeConfig;
@@ -24,11 +44,20 @@
 import com.android.server.UiServiceTestCase;
 import com.android.server.pm.PackageManagerService;
 
+import com.google.common.collect.ImmutableList;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 
@@ -36,17 +65,22 @@
 @SmallTest
 @RunWithLooper
 public class ScheduleConditionProviderTest extends UiServiceTestCase {
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
-    ScheduleConditionProvider mService;
+    private ScheduleConditionProvider mService;
+    private TestClock mClock = new TestClock();
+    @Mock private AlarmManager mAlarmManager;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        mContext.addMockSystemService(AlarmManager.class, mAlarmManager);
 
         Intent startIntent =
                 new Intent("com.android.server.notification.ScheduleConditionProvider");
         startIntent.setPackage("android");
-        ScheduleConditionProvider service = new ScheduleConditionProvider();
+        ScheduleConditionProvider service = new ScheduleConditionProvider(mClock);
         service.attach(
                 getContext(),
                 null,               // ActivityThread not actually used in Service
@@ -57,7 +91,7 @@
                 );
         service.onCreate();
         service.onBind(startIntent);
-        mService = spy(service);
+        mService = service;
    }
 
     @Test
@@ -343,6 +377,87 @@
         assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME, pi.getIntent().getPackage());
     }
 
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_MODES_HSUM)
+    public void onSubscribe_registersReceiverForAllUsers() {
+        Calendar now = getNow();
+        Uri condition = ZenModeConfig.toScheduleConditionId(getScheduleEndsInHour(now));
+
+        mService.onSubscribe(condition);
+
+        ArgumentCaptor<IntentFilter> filterCaptor = ArgumentCaptor.forClass(IntentFilter.class);
+        verify(mContext).registerReceiverForAllUsers(any(), filterCaptor.capture(), any(), any());
+        IntentFilter filter = filterCaptor.getValue();
+        assertThat(filter.actionsIterator()).isNotNull();
+        assertThat(ImmutableList.copyOf(filter.actionsIterator()))
+                .contains(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
+    }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_MODES_HSUM)
+    public void onAlarmClockChanged_storesNextAlarm() {
+        Instant scheduleStart = Instant.parse("2024-10-22T16:00:00Z");
+        Instant scheduleEnd = scheduleStart.plus(1, HOURS);
+
+        Instant now = scheduleStart.plus(15, MINUTES);
+        mClock.setNowMillis(now.toEpochMilli());
+
+        Uri condition = ZenModeConfig.toScheduleConditionId(
+                getOneHourSchedule(scheduleStart.atZone(ZoneId.systemDefault())));
+        mService.onSubscribe(condition);
+
+        // Now prepare to send an "alarm set for 16:30" broadcast.
+        Instant alarm = scheduleStart.plus(30, MINUTES);
+        ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(
+                BroadcastReceiver.class);
+        verify(mContext).registerReceiverForAllUsers(receiverCaptor.capture(), any(), any(), any());
+        BroadcastReceiver receiver = receiverCaptor.getValue();
+        receiver.setPendingResult(pendingResultForUserBroadcast(ActivityManager.getCurrentUser()));
+        when(mAlarmManager.getNextAlarmClock(anyInt())).thenReturn(
+                new AlarmManager.AlarmClockInfo(alarm.toEpochMilli(), null));
+
+        Intent intent = new Intent(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
+        receiver.onReceive(mContext, intent);
+
+        // The time for the alarm was stored in the ScheduleCalendar, meaning the rule will end when
+        // the next evaluation after that point happens.
+        ScheduleCalendar scheduleCalendar =
+                mService.getSubscriptions().values().stream().findFirst().get();
+        assertThat(scheduleCalendar.shouldExitForAlarm(alarm.toEpochMilli() - 1)).isFalse();
+        assertThat(scheduleCalendar.shouldExitForAlarm(alarm.toEpochMilli() + 1)).isTrue();
+
+        // But the next wakeup is unchanged, at the time of the schedule end (17:00).
+        verify(mAlarmManager, times(2)).setExact(eq(RTC_WAKEUP), eq(scheduleEnd.toEpochMilli()),
+                any());
+    }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_MODES_HSUM)
+    public void onAlarmClockChanged_forAnotherUser_isIgnored() {
+        Instant scheduleStart = Instant.parse("2024-10-22T16:00:00Z");
+        Instant now = scheduleStart.plus(15, MINUTES);
+        mClock.setNowMillis(now.toEpochMilli());
+
+        Uri condition = ZenModeConfig.toScheduleConditionId(
+                getOneHourSchedule(scheduleStart.atZone(ZoneId.systemDefault())));
+        mService.onSubscribe(condition);
+
+        // Now prepare to send an "alarm set for a different user" broadcast.
+        ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(
+                BroadcastReceiver.class);
+        verify(mContext).registerReceiverForAllUsers(receiverCaptor.capture(), any(), any(), any());
+        BroadcastReceiver receiver = receiverCaptor.getValue();
+
+        reset(mAlarmManager);
+        int anotherUser = ActivityManager.getCurrentUser() + 1;
+        receiver.setPendingResult(pendingResultForUserBroadcast(anotherUser));
+        Intent intent = new Intent(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
+        receiver.onReceive(mContext, intent);
+
+        // The alarm data was not read.
+        verify(mAlarmManager, never()).getNextAlarmClock(anyInt());
+    }
+
     private Calendar getNow() {
         Calendar now = new GregorianCalendar();
         now.set(Calendar.HOUR_OF_DAY, 14);
@@ -363,4 +478,38 @@
         info.endMinute = now.get(Calendar.MINUTE);
         return info;
     }
+
+    private static ZenModeConfig.ScheduleInfo getOneHourSchedule(ZonedDateTime start) {
+        ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
+        // Note: DayOfWeek.MONDAY doesn't match Calendar.MONDAY
+        info.days = new int[] { (start.getDayOfWeek().getValue() % 7) + 1 };
+        info.startHour = start.getHour();
+        info.startMinute = start.getMinute();
+        info.endHour = start.plusHours(1).getHour();
+        info.endMinute = start.plusHours(1).getMinute();
+        info.exitAtAlarm = true;
+        return info;
+    }
+
+    private static BroadcastReceiver.PendingResult pendingResultForUserBroadcast(int userId) {
+        return new BroadcastReceiver.PendingResult(0, "", new Bundle(), 0, false, false, null,
+                userId, 0);
+    }
+
+    private static class TestClock extends SimpleClock {
+        private long mNowMillis = 441644400000L;
+
+        private TestClock() {
+            super(ZoneOffset.UTC);
+        }
+
+        @Override
+        public long millis() {
+            return mNowMillis;
+        }
+
+        private void setNowMillis(long millis) {
+            mNowMillis = millis;
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
index cdb4542..d83ffd1 100644
--- a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
@@ -35,6 +35,7 @@
 
 import androidx.test.filters.MediumTest;
 
+import com.android.hardware.input.Flags;
 import com.android.internal.annotations.Keep;
 
 import junit.framework.Assert;
@@ -393,6 +394,17 @@
                 META_ON | CTRL_ON);
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_KEYBOARD_A11Y_SHORTCUT_CONTROL)
+    @DisableFlags(com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
+    public void testToggleTalkbackPress() {
+        testShortcutInternal("Meta + Alt + T -> Toggle talkback",
+                new int[]{META_KEY, ALT_KEY, KeyEvent.KEYCODE_T},
+                KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK,
+                KeyEvent.KEYCODE_T,
+                META_ON | ALT_ON);
+    }
+
     private void testShortcutInternal(String testName, int[] testKeys,
             @KeyGestureEvent.KeyGestureType int expectedKeyGestureType, int expectedKey,
             int expectedModifierState) {
@@ -699,4 +711,16 @@
                 sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS));
         mPhoneWindowManager.assertCloseAllDialogs();
     }
+
+    @Test
+    @EnableFlags(com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_SHORTCUT_CONTROL)
+    public void testKeyGestureToggleTalkback() {
+        Assert.assertTrue(
+                sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK));
+        mPhoneWindowManager.assertTalkBack(true);
+
+        Assert.assertTrue(
+                sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK));
+        mPhoneWindowManager.assertTalkBack(false);
+    }
 }
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 a85f866..62670b4 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -197,7 +197,7 @@
         }
 
         @Override
-        boolean toggleTalkback(int currentUserId) {
+        boolean toggleTalkback(int currentUserId, ShortcutSource source) {
             mIsTalkBackEnabled = !mIsTalkBackEnabled;
             return mIsTalkBackEnabled;
         }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 3bd5747..eb8bc91 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -40,7 +40,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -141,49 +140,49 @@
 
         // If everything is null, return null.
         assertNull(null, DisplayPolicy.chooseNavigationColorWindowLw(
-                null, null, NAV_BAR_BOTTOM));
+                null, null, true));
 
         // If no IME windows, return candidate window.
         assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw(
-                candidate, null, NAV_BAR_BOTTOM));
+                candidate, null, true));
         assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
-                dimmingImTarget, null, NAV_BAR_BOTTOM));
+                dimmingImTarget, null, true));
         assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
-                dimmingNonImTarget, null, NAV_BAR_BOTTOM));
+                dimmingNonImTarget, null, true));
 
         // If IME is not visible, return candidate window.
         assertEquals(null, DisplayPolicy.chooseNavigationColorWindowLw(
-                null, invisibleIme, NAV_BAR_BOTTOM));
+                null, invisibleIme, true));
         assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw(
-                candidate, invisibleIme, NAV_BAR_BOTTOM));
+                candidate, invisibleIme, true));
         assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
-                dimmingImTarget, invisibleIme, NAV_BAR_BOTTOM));
+                dimmingImTarget, invisibleIme, true));
         assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
-                dimmingNonImTarget, invisibleIme, NAV_BAR_BOTTOM));
+                dimmingNonImTarget, invisibleIme, true));
 
         // If IME is visible, return candidate when the candidate window is not dimming.
         assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
-                null, visibleIme, NAV_BAR_BOTTOM));
+                null, visibleIme, true));
         assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
-                candidate, visibleIme, NAV_BAR_BOTTOM));
+                candidate, visibleIme, true));
 
         // If IME is visible and the candidate window is dimming, checks whether the dimming window
         // can be IME tartget or not.
         assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
-                dimmingImTarget, visibleIme, NAV_BAR_BOTTOM));
+                dimmingImTarget, visibleIme, true));
         assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
-                dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM));
+                dimmingNonImTarget, visibleIme, true));
 
         // Only IME windows that have FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS should be navigation color
         // window.
         assertEquals(null, DisplayPolicy.chooseNavigationColorWindowLw(
-                null, imeNonDrawNavBar, NAV_BAR_BOTTOM));
+                null, imeNonDrawNavBar, true));
         assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw(
-                candidate, imeNonDrawNavBar, NAV_BAR_BOTTOM));
+                candidate, imeNonDrawNavBar, true));
         assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
-                dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
+                dimmingImTarget, imeNonDrawNavBar, true));
         assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
-                dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
+                dimmingNonImTarget, imeNonDrawNavBar, true));
     }
 
     @Test
@@ -196,32 +195,32 @@
         final WindowState nonDrawBarIme = createInputMethodWindow(true, false, false);
 
         assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow(
-                drawBarWin, null, NAV_BAR_BOTTOM));
+                drawBarWin, null, true));
         assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
-                null, null, NAV_BAR_BOTTOM));
+                null, null, true));
         assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
-                nonDrawBarWin, null, NAV_BAR_BOTTOM));
+                nonDrawBarWin, null, true));
 
         assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow(
-                drawBarWin, visibleIme, NAV_BAR_BOTTOM));
+                drawBarWin, visibleIme, true));
         assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow(
-                null, visibleIme, NAV_BAR_BOTTOM));
+                null, visibleIme, true));
         assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow(
-                nonDrawBarWin, visibleIme, NAV_BAR_BOTTOM));
+                nonDrawBarWin, visibleIme, true));
 
         assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow(
-                drawBarWin, invisibleIme, NAV_BAR_BOTTOM));
+                drawBarWin, invisibleIme, true));
         assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
-                null, invisibleIme, NAV_BAR_BOTTOM));
+                null, invisibleIme, true));
         assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
-                nonDrawBarWin, invisibleIme, NAV_BAR_BOTTOM));
+                nonDrawBarWin, invisibleIme, true));
 
         assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow(
-                drawBarWin, nonDrawBarIme, NAV_BAR_BOTTOM));
+                drawBarWin, nonDrawBarIme, true));
         assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
-                null, nonDrawBarIme, NAV_BAR_BOTTOM));
+                null, nonDrawBarIme, true));
         assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
-                nonDrawBarWin, nonDrawBarIme, NAV_BAR_BOTTOM));
+                nonDrawBarWin, nonDrawBarIme, true));
     }
 
     @SetupWindows(addWindows = W_NAVIGATION_BAR)
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index 00ecd00..546b1ba 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -19,11 +19,9 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
 import static android.view.Surface.ROTATION_0;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -208,7 +206,7 @@
             if (mSystemDecorations) {
                 doReturn(true).when(newDisplay).supportsSystemDecorations();
                 doReturn(true).when(displayPolicy).hasNavigationBar();
-                doReturn(NAV_BAR_BOTTOM).when(displayPolicy).navigationBarPosition(anyInt());
+                doReturn(true).when(displayPolicy).hasBottomNavigationBar();
             } else {
                 doReturn(false).when(displayPolicy).hasNavigationBar();
                 doReturn(false).when(displayPolicy).hasStatusBar();
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 79b3a7c..94be3d4 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -127,7 +127,9 @@
 
     /**
      * Exception from the satellite service containing the {@link SatelliteResult} error code.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static class SatelliteException extends Exception {
         @SatelliteResult private final int mErrorCode;
@@ -257,140 +259,210 @@
 
     /**
      * The request was successfully processed.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_SUCCESS = 0;
+
     /**
      * A generic error which should be used only when other specific errors cannot be used.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_ERROR = 1;
+
     /**
      * Error received from the satellite server.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_SERVER_ERROR = 2;
+
     /**
      * Error received from the vendor service. This generic error code should be used
      * only when the error cannot be mapped to other specific service error codes.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_SERVICE_ERROR = 3;
+
     /**
      * Error received from satellite modem. This generic error code should be used only when
      * the error cannot be mapped to other specific modem error codes.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_MODEM_ERROR = 4;
+
     /**
      * Error received from the satellite network. This generic error code should be used only when
      * the error cannot be mapped to other specific network error codes.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_NETWORK_ERROR = 5;
+
     /**
      * Telephony is not in a valid state to receive requests from clients.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_INVALID_TELEPHONY_STATE = 6;
+
     /**
      * Satellite modem is not in a valid state to receive requests from clients.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_INVALID_MODEM_STATE = 7;
+
     /**
      * Either vendor service, or modem, or Telephony framework has received a request with
      * invalid arguments from its clients.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_INVALID_ARGUMENTS = 8;
+
     /**
      * Telephony framework failed to send a request or receive a response from the vendor service
      * or satellite modem due to internal error.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_REQUEST_FAILED = 9;
+
     /**
      * Radio did not start or is resetting.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_RADIO_NOT_AVAILABLE = 10;
+
     /**
      * The request is not supported by either the satellite modem or the network.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_REQUEST_NOT_SUPPORTED = 11;
+
     /**
      * Satellite modem or network has no resources available to handle requests from clients.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_NO_RESOURCES = 12;
+
     /**
      * Satellite service is not provisioned yet.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_SERVICE_NOT_PROVISIONED = 13;
+
     /**
      * Satellite service provision is already in progress.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS = 14;
+
     /**
      * The ongoing request was aborted by either the satellite modem or the network.
      * This error is also returned when framework decides to abort current send request as one
      * of the previous send request failed.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_REQUEST_ABORTED = 15;
+
     /**
      * The device/subscriber is barred from accessing the satellite service.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_ACCESS_BARRED = 16;
+
     /**
      * Satellite modem timeout to receive ACK or response from the satellite network after
      * sending a request to the network.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_NETWORK_TIMEOUT = 17;
+
     /**
      * Satellite network is not reachable from the modem.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_NOT_REACHABLE = 18;
+
     /**
      * The device/subscriber is not authorized to register with the satellite service provider.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_NOT_AUTHORIZED = 19;
+
     /**
      * The device does not support satellite.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_NOT_SUPPORTED = 20;
 
     /**
      * The current request is already in-progress.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_REQUEST_IN_PROGRESS = 21;
 
     /**
      * Satellite modem is currently busy due to which current request cannot be processed.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_MODEM_BUSY = 22;
 
     /**
      * Telephony process is not currently available or satellite is not supported.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_ILLEGAL_STATE = 23;
 
     /**
      * Telephony framework timeout to receive ACK or response from the satellite modem after
      * sending a request to the modem.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_MODEM_TIMEOUT = 24;
 
@@ -475,27 +547,41 @@
     /**
      * Unknown Non-Terrestrial radio technology. This generic radio technology should be used
      * only when the radio technology cannot be mapped to other specific radio technologies.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int NT_RADIO_TECHNOLOGY_UNKNOWN = 0;
+
     /**
      * 3GPP NB-IoT (Narrowband Internet of Things) over Non-Terrestrial-Networks technology.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int NT_RADIO_TECHNOLOGY_NB_IOT_NTN = 1;
+
     /**
      * 3GPP 5G NR over Non-Terrestrial-Networks technology.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int NT_RADIO_TECHNOLOGY_NR_NTN = 2;
+
     /**
      * 3GPP eMTC (enhanced Machine-Type Communication) over Non-Terrestrial-Networks technology.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int NT_RADIO_TECHNOLOGY_EMTC_NTN = 3;
+
     /**
      * Proprietary technology.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int NT_RADIO_TECHNOLOGY_PROPRIETARY = 4;
 
@@ -510,16 +596,35 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface NTRadioTechnology {}
 
-    /** Suggested device hold position is unknown. */
+    /**
+     * Suggested device hold position is unknown.
+     * @hide
+     */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int DEVICE_HOLD_POSITION_UNKNOWN = 0;
-    /** User is suggested to hold the device in portrait mode. */
+
+    /**
+     * User is suggested to hold the device in portrait mode.
+     * @hide
+     */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int DEVICE_HOLD_POSITION_PORTRAIT = 1;
-    /** User is suggested to hold the device in landscape mode with left hand. */
+
+    /**
+     * User is suggested to hold the device in landscape mode with left hand.
+     * @hide
+     */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int DEVICE_HOLD_POSITION_LANDSCAPE_LEFT = 2;
-    /** User is suggested to hold the device in landscape mode with right hand. */
+
+    /**
+     * User is suggested to hold the device in landscape mode with right hand.
+     * @hide
+     */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int DEVICE_HOLD_POSITION_LANDSCAPE_RIGHT = 3;
 
@@ -533,18 +638,37 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface DeviceHoldPosition {}
 
-    /** Display mode is unknown. */
+    /**
+     *  Display mode is unknown.
+     * @hide
+     */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int DISPLAY_MODE_UNKNOWN = 0;
-    /** Display mode of the device used for satellite communication for non-foldable phones. */
+
+    /**
+     * Display mode of the device used for satellite communication for non-foldable phones.
+     * @hide
+     */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int DISPLAY_MODE_FIXED = 1;
-    /** Display mode of the device used for satellite communication for foldabale phones when the
-     * device is opened. */
+
+    /**
+     * Display mode of the device used for satellite communication for foldabale phones when the
+     * device is opened.
+     * @hide
+     */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int DISPLAY_MODE_OPENED = 2;
-    /** Display mode of the device used for satellite communication for foldabable phones when the
-     * device is closed. */
+
+    /**
+     * Display mode of the device used for satellite communication for foldabable phones when the
+     * device is closed.
+     * @hide
+     */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int DISPLAY_MODE_CLOSED = 3;
 
@@ -561,13 +685,18 @@
     /**
      * The emergency call is handed over to oem-enabled satellite SOS messaging. SOS messages are
      * sent to SOS providers, which will then forward the messages to emergency providers.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS = 1;
+
     /**
      * The emergency call is handed over to carrier-enabled satellite T911 messaging. T911 messages
      * are sent directly to local emergency providers.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
     public static final int EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911 = 2;
 
@@ -614,7 +743,10 @@
      * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void requestEnabled(@NonNull EnableRequestAttributes attributes,
@@ -660,7 +792,10 @@
      *                 will return a {@link SatelliteException} with the {@link SatelliteResult}.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void requestIsEnabled(@NonNull @CallbackExecutor Executor executor,
@@ -717,7 +852,10 @@
      *                 will return a {@link SatelliteException} with the {@link SatelliteResult}.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void requestIsDemoModeEnabled(@NonNull @CallbackExecutor Executor executor,
@@ -774,7 +912,10 @@
      *                 will return a {@link SatelliteException} with the {@link SatelliteResult}.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void requestIsEmergencyModeEnabled(@NonNull @CallbackExecutor Executor executor,
@@ -832,7 +973,10 @@
      *                 service is supported on the device and {@code false} otherwise.
      *                 If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
      *                 will return a {@link SatelliteException} with the {@link SatelliteResult}.
+     *
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void requestIsSupported(@NonNull @CallbackExecutor Executor executor,
             @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
@@ -887,7 +1031,10 @@
      *                 will return a {@link SatelliteException} with the {@link SatelliteResult}.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void requestCapabilities(@NonNull @CallbackExecutor Executor executor,
@@ -936,56 +1083,80 @@
     /**
      * The default state indicating that datagram transfer is idle.
      * This should be sent if there are no message transfer activity happening.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE = 0;
+
     /**
      * A transition state indicating that a datagram is being sent.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING = 1;
+
     /**
      * An end state indicating that datagram sending completed successfully.
      * After datagram transfer completes, {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE}
      * will be sent if no more messages are pending.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS = 2;
+
     /**
      * An end state indicating that datagram sending completed with a failure.
      * After datagram transfer completes, {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE}
      * must be sent before reporting any additional datagram transfer state changes. All pending
      * messages will be reported as failed, to the corresponding applications.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED = 3;
+
     /**
      * A transition state indicating that a datagram is being received.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING = 4;
+
     /**
      * An end state indicating that datagram receiving completed successfully.
      * After datagram transfer completes, {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE}
      * will be sent if no more messages are pending.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS = 5;
+
     /**
      * An end state indicating that datagram receive operation found that there are no
      * messages to be retrieved from the satellite.
      * After datagram transfer completes, {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE}
      * will be sent if no more messages are pending.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE = 6;
+
     /**
      * An end state indicating that datagram receive completed with a failure.
      * After datagram transfer completes, {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE}
      * will be sent if no more messages are pending.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED = 7;
+
     /**
      * A transition state indicating that Telephony is waiting for satellite modem to connect to a
      * satellite network before sending a datagram or polling for datagrams. If the satellite modem
@@ -994,14 +1165,19 @@
      * {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING} will be sent. Otherwise,
      * either {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED} or
      * {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED} will be sent.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT = 8;
+
     /**
      * The datagram transfer state is unknown. This generic datagram transfer state should be used
      * only when the datagram transfer state cannot be mapped to other specific datagram transfer
      * states.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN = -1;
 
@@ -1024,58 +1200,86 @@
 
     /**
      * Satellite modem is in idle state.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_MODEM_STATE_IDLE = 0;
+
     /**
      * Satellite modem is listening for incoming datagrams.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_MODEM_STATE_LISTENING = 1;
+
     /**
      * Satellite modem is sending and/or receiving datagrams.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING = 2;
+
     /**
      * Satellite modem is retrying to send and/or receive datagrams.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_MODEM_STATE_DATAGRAM_RETRYING = 3;
+
     /**
      * Satellite modem is powered off.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_MODEM_STATE_OFF = 4;
+
     /**
      * Satellite modem is unavailable.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_MODEM_STATE_UNAVAILABLE = 5;
+
     /**
      * The satellite modem is powered on but the device is not registered to a satellite cell.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_MODEM_STATE_NOT_CONNECTED = 6;
+
     /**
      * The satellite modem is powered on and the device is registered to a satellite cell.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_MODEM_STATE_CONNECTED = 7;
+
     /**
      * The satellite modem is being powered on.
      * @hide
      */
     public static final int SATELLITE_MODEM_STATE_ENABLING_SATELLITE = 8;
+
     /**
      * The satellite modem is being powered off.
      * @hide
      */
     public static final int SATELLITE_MODEM_STATE_DISABLING_SATELLITE = 9;
+
     /**
      * Satellite modem state is unknown. This generic modem state should be used only when the
      * modem state cannot be mapped to other specific modem states.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_MODEM_STATE_UNKNOWN = -1;
 
@@ -1099,43 +1303,56 @@
     /**
      * Datagram type is unknown. This generic datagram type should be used only when the
      * datagram type cannot be mapped to other specific datagram types.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int DATAGRAM_TYPE_UNKNOWN = 0;
+
     /**
      * Datagram type indicating that the datagram to be sent or received is of type SOS message.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int DATAGRAM_TYPE_SOS_MESSAGE = 1;
+
     /**
      * Datagram type indicating that the datagram to be sent or received is of type
      * location sharing.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int DATAGRAM_TYPE_LOCATION_SHARING = 2;
+
     /**
      * This type of datagram is used to keep the device in satellite connected state or check if
      * there is any incoming message.
      * @hide
      */
     public static final int DATAGRAM_TYPE_KEEP_ALIVE = 3;
+
     /**
      * Datagram type indicating that the datagram to be sent or received is of type SOS message and
      * is the last message to emergency service provider indicating still needs help.
      * @hide
      */
     public static final int DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP = 4;
+
     /**
      * Datagram type indicating that the datagram to be sent or received is of type SOS message and
      * is the last message to emergency service provider indicating no more help is needed.
      * @hide
      */
     public static final int DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED = 5;
+
     /**
      * Datagram type indicating that the message to be sent or received is of type SMS.
      * @hide
      */
     public static final int DATAGRAM_TYPE_SMS = 6;
+
     /**
      * Datagram type indicating that the message to be sent is an SMS checking
      * for pending incoming SMS.
@@ -1166,7 +1383,9 @@
     /**
      * Satellite communication restricted by geolocation. This can be
      * triggered based upon geofence input provided by carrier to enable or disable satellite.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION = 1;
 
@@ -1174,7 +1393,9 @@
      * Satellite communication restricted by entitlement server. This can be triggered based on
      * the EntitlementStatus value received from the entitlement server to enable or disable
      * satellite.
+     * @hide
      */
+    @SystemApi
     @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT = 2;
 
@@ -1201,7 +1422,10 @@
      * @param callback The callback to notify of satellite transmission updates.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     @SuppressWarnings("SamShouldBeLast")
@@ -1284,7 +1508,10 @@
      * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void stopTransmissionUpdates(@NonNull SatelliteTransmissionUpdateCallback callback,
@@ -1342,7 +1569,10 @@
      * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void provisionService(@NonNull String token, @NonNull byte[] provisionData,
@@ -1397,7 +1627,10 @@
      * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void deprovisionService(@NonNull String token,
@@ -1440,7 +1673,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     @SatelliteResult public int registerForProvisionStateChanged(
@@ -1492,7 +1728,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void unregisterForProvisionStateChanged(
@@ -1530,7 +1769,10 @@
      *                 will return a {@link SatelliteException} with the {@link SatelliteResult}.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void requestIsProvisioned(@NonNull @CallbackExecutor Executor executor,
@@ -1585,7 +1827,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     @SatelliteResult public int registerForModemStateChanged(
@@ -1639,7 +1884,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void unregisterForModemStateChanged(
@@ -1679,7 +1927,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     @SatelliteResult public int registerForIncomingDatagram(
@@ -1735,7 +1986,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void unregisterForIncomingDatagram(@NonNull SatelliteDatagramCallback callback) {
@@ -1773,7 +2027,10 @@
      * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void pollPendingDatagrams(@NonNull @CallbackExecutor Executor executor,
@@ -1828,7 +2085,10 @@
      * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void sendDatagram(@DatagramType int datagramType,
@@ -1876,7 +2136,10 @@
      *                 will return a {@link SatelliteException} with the {@link SatelliteResult}.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void requestIsCommunicationAllowedForCurrentLocation(
@@ -1934,7 +2197,10 @@
      *                 will return a {@link SatelliteException} with the {@link SatelliteResult}.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void requestTimeForNextSatelliteVisibility(@NonNull @CallbackExecutor Executor executor,
@@ -1992,7 +2258,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void setDeviceAlignedWithSatellite(boolean isAligned) {
@@ -2032,7 +2301,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalArgumentException if the subscription is invalid.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
     public void requestAttachEnabledForCarrier(int subId, boolean enableSatellite,
@@ -2066,7 +2338,10 @@
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
      * @throws IllegalArgumentException if the subscription is invalid.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
     public void requestIsAttachEnabledForCarrier(int subId,
@@ -2091,7 +2366,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalArgumentException if the subscription is invalid.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
     public void addAttachRestrictionForCarrier(int subId,
@@ -2136,7 +2414,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalArgumentException if the subscription is invalid.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
     public void removeAttachRestrictionForCarrier(int subId,
@@ -2180,7 +2461,10 @@
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
      * @throws IllegalArgumentException if the subscription is invalid.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @SatelliteCommunicationRestrictionReason
     @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
@@ -2230,7 +2514,10 @@
      * {@link SatelliteException} with the {@link SatelliteResult}.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void requestNtnSignalStrength(@NonNull @CallbackExecutor Executor executor,
@@ -2293,7 +2580,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void registerForNtnSignalStrengthChanged(@NonNull @CallbackExecutor Executor executor,
@@ -2342,7 +2632,10 @@
      * @throws IllegalArgumentException if the callback is not valid or has already been
      * unregistered.
      * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void unregisterForNtnSignalStrengthChanged(@NonNull NtnSignalStrengthCallback callback) {
@@ -2376,7 +2669,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     @SatelliteResult public int registerForCapabilitiesChanged(
@@ -2419,7 +2715,10 @@
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public void unregisterForCapabilitiesChanged(
@@ -2452,7 +2751,10 @@
      *
      * @return List of plmn for carrier satellite service. If no plmn is available, empty list will
      * be returned.
+     *
+     * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
     @NonNull public List<String> getSatellitePlmnsForCarrier(int subId) {
diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py
index 006a0290..3bde929 100755
--- a/tools/fonts/fontchain_linter.py
+++ b/tools/fonts/fontchain_linter.py
@@ -10,6 +10,14 @@
 
 from fontTools import ttLib
 
+# TODO(nona): Remove hard coded font version and unicode versions.
+# Figure out a way of giving this information with command lines.
+EMOJI_FONT_TO_UNICODE_MAP = {
+    '2.034': 15.0,
+    '2.042': 15.1,
+    '2.047': 16.0,
+}
+
 EMOJI_VS = 0xFE0F
 
 LANG_TO_SCRIPT = {
@@ -217,9 +225,8 @@
 
 
 class FontRecord(object):
-    def __init__(self, name, psName, scripts, variant, weight, style, fallback_for, font):
+    def __init__(self, name, scripts, variant, weight, style, fallback_for, font):
         self.name = name
-        self.psName = psName
         self.scripts = scripts
         self.variant = variant
         self.weight = weight
@@ -282,13 +289,23 @@
             m = trim_re.match(font_file)
             font_file = m.group(1)
 
-            weight = int(child.get('weight'))
-            assert weight % 100 == 0, (
-                'Font weight "%d" is not a multiple of 100.' % weight)
+            # In case of variable font and it supports `wght` axis, the weight attribute can be
+            # dropped which is automatically adjusted at runtime.
+            if 'weight' in child:
+                weight = int(child.get('weight'))
+                assert weight % 100 == 0, (
+                    'Font weight "%d" is not a multiple of 100.' % weight)
+            else:
+                weight = None
 
-            style = child.get('style')
-            assert style in {'normal', 'italic'}, (
-                'Unknown style "%s"' % style)
+            # In case of variable font and it supports `ital` or `slnt` axes, the style attribute
+            # can be dropped which is automatically adjusted at runtime.
+            if 'style' in child:
+                style = child.get('style')
+                assert style in {'normal', 'italic'}, (
+                    'Unknown style "%s"' % style)
+            else:
+                style = None
 
             fallback_for = child.get('fallbackFor')
 
@@ -306,7 +323,6 @@
 
             record = FontRecord(
                 name,
-                child.get('postScriptName'),
                 frozenset(scripts),
                 variant,
                 weight,
@@ -357,6 +373,11 @@
     # regional indicator A..Z
     return 0x1F1E6 <= x <= 0x1F1FF
 
+def is_flag_sequence(seq):
+    if type(seq) == int:
+      return False
+    len(seq) == 2 and is_regional_indicator(seq[0]) and is_regional_indicator(seq[1])
+
 def is_tag(x):
     # tag block
     return 0xE0000 <= x <= 0xE007F
@@ -391,17 +412,43 @@
         if "meta" in ttf:
             assert 'Emji' not in ttf["meta"].data, 'NotoColorEmoji MUST be a compat font'
 
+def is_flag_emoji(font):
+    return 0x1F1E6 in get_best_cmap(font)
+
+def emoji_font_version_to_unicode_version(font_version):
+    version_str = '%.3f' % font_version
+    assert version_str in EMOJI_FONT_TO_UNICODE_MAP, 'Unknown emoji font verion: %s' % version_str
+    return EMOJI_FONT_TO_UNICODE_MAP[version_str]
+
 
 def check_emoji_font_coverage(emoji_fonts, all_emoji, equivalent_emoji):
     coverages = []
+    emoji_font_version = 0
+    emoji_flag_font_version = 0
     for emoji_font in emoji_fonts:
         coverages.append(get_emoji_map(emoji_font))
 
+        # Find the largest version of the installed emoji font.
+        version = open_font(emoji_font)['head'].fontRevision
+        if is_flag_emoji(emoji_font):
+          emoji_flag_font_version = max(emoji_flag_font_version, version)
+        else:
+          emoji_font_version = max(emoji_font_version, version)
+
+    emoji_flag_unicode_version = emoji_font_version_to_unicode_version(emoji_flag_font_version)
+    emoji_unicode_version = emoji_font_version_to_unicode_version(emoji_font_version)
+
     errors = []
 
     for sequence in all_emoji:
         if all([sequence not in coverage for coverage in coverages]):
-            errors.append('%s is not supported in the emoji font.' % printable(sequence))
+            sequence_version = float(_age_by_chars[sequence])
+            if is_flag_sequence(sequence):
+                if sequence_version <= emoji_flag_unicode_version:
+                    errors.append('%s is not supported in the emoji font.' % printable(sequence))
+            else:
+                if sequence_version <= emoji_unicode_version:
+                    errors.append('%s is not supported in the emoji font.' % printable(sequence))
 
     for coverage in coverages:
         for sequence in coverage:
@@ -480,6 +527,19 @@
                 repr(missing_text_chars))
 
 
+def parse_unicode_seq(chars):
+    if ' ' in chars:  # character sequence
+        sequence = [int(ch, 16) for ch in chars.split(' ')]
+        additions = [tuple(sequence)]
+    elif '..' in chars:  # character range
+        char_start, char_end = chars.split('..')
+        char_start = int(char_start, 16)
+        char_end = int(char_end, 16)
+        additions = range(char_start, char_end+1)
+    else:  # single character
+        additions = [int(chars, 16)]
+    return additions
+
 # Setting reverse to true returns a dictionary that maps the values to sets of
 # characters, useful for some binary properties. Otherwise, we get a
 # dictionary that maps characters to the property values, assuming there's only
@@ -501,16 +561,8 @@
             chars = chars.strip()
             prop = prop.strip()
 
-            if ' ' in chars:  # character sequence
-                sequence = [int(ch, 16) for ch in chars.split(' ')]
-                additions = [tuple(sequence)]
-            elif '..' in chars:  # character range
-                char_start, char_end = chars.split('..')
-                char_start = int(char_start, 16)
-                char_end = int(char_end, 16)
-                additions = range(char_start, char_end+1)
-            else:  # singe character
-                additions = [int(chars, 16)]
+            additions = parse_unicode_seq(chars)
+
             if reverse:
                 output_dict[prop].update(additions)
             else:
@@ -519,6 +571,32 @@
                     output_dict[addition] = prop
     return output_dict
 
+def parse_sequence_age(file_path):
+    VERSION_RE = re.compile(r'E([\d\.]+)')
+    output_dict = {}
+    with open(file_path) as datafile:
+        for line in datafile:
+            comment = ''
+            if '#' in line:
+                hash_pos = line.index('#')
+                comment = line[hash_pos + 1:].strip()
+                line = line[:hash_pos]
+            line = line.strip()
+            if not line:
+                continue
+
+            chars = line[:line.index(';')].strip()
+
+            m = VERSION_RE.match(comment)
+            assert m, 'Version not found: unknown format: %s' % line
+            version = m.group(1)
+
+            additions = parse_unicode_seq(chars)
+
+            for addition in additions:
+                assert addition not in output_dict
+                output_dict[addition] = version
+    return output_dict
 
 def parse_emoji_variants(file_path):
     emoji_set = set()
@@ -543,7 +621,7 @@
 
 
 def parse_ucd(ucd_path):
-    global _emoji_properties, _chars_by_age
+    global _emoji_properties, _chars_by_age, _age_by_chars
     global _text_variation_sequences, _emoji_variation_sequences
     global _emoji_sequences, _emoji_zwj_sequences
     _emoji_properties = parse_unicode_datafile(
@@ -555,6 +633,10 @@
 
     _chars_by_age = parse_unicode_datafile(
         path.join(ucd_path, 'DerivedAge.txt'), reverse=True)
+    _age_by_chars = parse_unicode_datafile(
+        path.join(ucd_path, 'DerivedAge.txt'))
+    _age_by_chars.update(parse_sequence_age(
+        path.join(ucd_path, 'emoji-sequences.txt')))
     sequences = parse_emoji_variants(
         path.join(ucd_path, 'emoji-variation-sequences.txt'))
     _text_variation_sequences, _emoji_variation_sequences = sequences
@@ -743,44 +825,12 @@
                 break
             assert_font_supports_none_of_chars(record.font, cjk_punctuation, name)
 
-def getPostScriptName(font):
-  font_file, index = font
-  font_path = path.join(_fonts_dir, font_file)
-  if index is not None:
-      # Use the first font file in the collection for resolving post script name.
-      ttf = ttLib.TTFont(font_path, fontNumber=0)
-  else:
-      ttf = ttLib.TTFont(font_path)
-
-  nameTable = ttf['name']
-  for name in nameTable.names:
-      if (name.nameID == 6 and name.platformID == 3 and name.platEncID == 1
-          and name.langID == 0x0409):
-          return str(name)
-
-def check_canonical_name():
-    for record in _all_fonts:
-        file_name, index = record.font
-
-        psName = getPostScriptName(record.font)
-        if record.psName:
-            # If fonts element has postScriptName attribute, it should match with the PostScript
-            # name in the name table.
-            assert psName == record.psName, ('postScriptName attribute %s should match with %s' % (
-                record.psName, psName))
-        else:
-            # If fonts element doesn't have postScriptName attribute, the file name should match
-            # with the PostScript name in the name table.
-            assert psName == file_name[:-4], ('file name %s should match with %s' % (
-                file_name, psName))
-
-
 def main():
     global _fonts_dir
     target_out = sys.argv[1]
     _fonts_dir = path.join(target_out, 'fonts')
 
-    fonts_xml_path = path.join(target_out, 'etc', 'fonts.xml')
+    fonts_xml_path = path.join(target_out, 'etc', 'font_fallback.xml')
 
     parse_fonts_xml(fonts_xml_path)
 
@@ -793,8 +843,6 @@
 
     check_cjk_punctuation()
 
-    check_canonical_name()
-
     check_emoji = sys.argv[2]
     if check_emoji == 'true':
         ucd_path = sys.argv[3]